From 8756ace462ab94e540d53c633b7e76c21b7a6bcd Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Mon, 13 Mar 2023 21:32:05 -0230 Subject: inverse trig functions --- src/function.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/input.rs | 4 +++- src/lib.rs | 59 ++++--------------------------------------------------- 3 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 src/function.rs 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 { + 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::() { diff --git a/src/lib.rs b/src/lib.rs index 039258c..db316f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, @@ -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 { - 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) -- cgit v1.2.3