diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2023-03-13 21:32:05 -0230 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2023-03-13 21:32:05 -0230 |
| commit | 8756ace462ab94e540d53c633b7e76c21b7a6bcd (patch) | |
| tree | 4ae8e0025aa8c25af8f15164ba06dd98f9a6324b | |
| parent | c83c2315dd45bb0bc590995ea0899a0ebd1b59dc (diff) | |
| download | pfc-8756ace462ab94e540d53c633b7e76c21b7a6bcd.zip | |
inverse trig functions
| -rw-r--r-- | src/function.rs | 61 | ||||
| -rw-r--r-- | src/input.rs | 4 | ||||
| -rw-r--r-- | src/lib.rs | 59 |
3 files changed, 68 insertions, 56 deletions
diff --git a/src/function.rs b/src/function.rs new file mode 100644 index 0000000..bb6462d --- /dev/null +++ b/src/function.rs @@ -0,0 +1,61 @@ +use crate::AngleMode; + +pub enum Function { + Sin, // Sine + Cos, // Cosine + Tan, // Tangent + Asin, // Inverse sine + Acos, // Inverse cosine + Atan, // Inverse tangent + Deg, // Convert from radians to degrees + Rad, // Convert from degrees to radians +} + +impl Function { + pub fn parse(s: &str) -> Result<Self, ParseFunctionError> { + match s { + "sin" => Ok(Self::Sin), + "cos" => Ok(Self::Cos), + "tan" => Ok(Self::Tan), + "asin" => Ok(Self::Asin), + "acos" => Ok(Self::Acos), + "atan" => Ok(Self::Atan), + "deg" => Ok(Self::Deg), + "rad" => Ok(Self::Rad), + _ => Err(ParseFunctionError(s.to_string())), + } + } + + pub fn call(&self, val: f64, angle_mode: AngleMode) -> f64 { + match self { + Self::Sin => match angle_mode { + AngleMode::Degrees => val.to_radians().sin(), + AngleMode::Radians => val.sin(), + }, + Self::Cos => match angle_mode { + AngleMode::Degrees => val.to_radians().cos(), + AngleMode::Radians => val.cos(), + }, + Self::Tan => match angle_mode { + AngleMode::Degrees => val.to_radians().tan(), + AngleMode::Radians => val.tan(), + }, + Self::Asin => match angle_mode { + AngleMode::Degrees => val.asin().to_degrees(), + AngleMode::Radians => val.asin(), + }, + Self::Acos => match angle_mode { + AngleMode::Degrees => val.acos().to_degrees(), + AngleMode::Radians => val.acos(), + }, + Self::Atan => match angle_mode { + AngleMode::Degrees => val.atan().to_degrees(), + AngleMode::Radians => val.atan(), + }, + Self::Deg => val.to_degrees(), + Self::Rad => val.to_radians(), + } + } +} + +pub struct ParseFunctionError(String); diff --git a/src/input.rs b/src/input.rs index dbfe763..4de615f 100644 --- a/src/input.rs +++ b/src/input.rs @@ -32,7 +32,9 @@ impl Calculator { } KeyCode::Enter => { if let Ok(func) = Function::parse(&self.input_buffer) { - self.call_function(func); + if let Some(val) = self.stack.pop() { + self.stack.push(func.call(val, self.angle_mode)); + } } else if let Ok(c) = Constant::parse(&self.input_buffer) { self.stack.push(c.value()); } else if let Ok(bu) = self.input_buffer.parse::<f64>() { @@ -3,9 +3,12 @@ use std::{ fmt::{self, Display, Formatter}, }; +mod function; mod input; pub mod ui; +pub use function::Function; + #[derive(Default)] pub struct Calculator { stack: Vec<f64>, @@ -35,41 +38,10 @@ impl Calculator { Operator::Exp => lhs.powf(rhs), }); } - - fn call_function(&mut self, func: Function) { - let mut val = match self.stack.pop() { - Some(v) => v, - None => { - return; - } - }; - self.stack.push(match func { - Function::Sin => { - if self.angle_mode == AngleMode::Degrees { - val = val.to_radians(); - } - val.sin() - } - Function::Cos => { - if self.angle_mode == AngleMode::Degrees { - val = val.to_radians(); - } - val.cos() - } - Function::Tan => { - if self.angle_mode == AngleMode::Degrees { - val = val.to_radians(); - } - val.tan() - } - Function::Deg => val.to_degrees(), - Function::Rad => val.to_radians(), - }); - } } #[derive(Default, Copy, Clone, PartialEq)] -enum AngleMode { +pub enum AngleMode { #[default] Degrees, Radians, @@ -120,29 +92,6 @@ impl Operator { struct ParseOperatorError(char); -enum Function { - Sin, // Sine - Cos, // Cosine - Tan, // Tangent - Deg, // Convert from radians to degrees - Rad, // Convert from degrees to radians -} - -impl Function { - fn parse(s: &str) -> Result<Self, ParseFunctionError> { - match s { - "sin" => Ok(Self::Sin), - "cos" => Ok(Self::Cos), - "tan" => Ok(Self::Tan), - "deg" => Ok(Self::Deg), - "rad" => Ok(Self::Rad), - _ => Err(ParseFunctionError(s.to_string())), - } - } -} - -struct ParseFunctionError(String); - enum Constant { Pi, // Archimedes’ constant (π) E, // Euler's number (e) |