diff --git a/src/evaluator.rs b/src/evaluator.rs index b33ce96..b216e10 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -83,10 +83,32 @@ fn evaluate_node(ast_node: &AstNode) -> Result { return Err(format!("exp() only accepts UnitType::NoUnit").to_string()) } }, - // Ceil - // Floor - // Round - // Fabs, + Round => { + // .quantize() rounds .5 to nearest even integer, so we correct that + let mut result = child_answer.value.quantize(d128!(1)); + let rounding_change = result - child_answer.value; + // If the result was rounded down by 0.5, correct by +1 + if rounding_change == d128!(-0.5) { result += d128!(1); } + return Ok(Answer::new(result, child_answer.unit)) + }, + Ceil => { + let mut result = child_answer.value.quantize(d128!(1)); + let rounding_change = result - child_answer.value; + if rounding_change.is_negative() { result += d128!(1); } + return Ok(Answer::new(result, child_answer.unit)) + }, + Floor => { + let mut result = child_answer.value.quantize(d128!(1)); + let rounding_change = result - child_answer.value; + if !rounding_change.is_negative() { result -= d128!(1); } + return Ok(Answer::new(result, child_answer.unit)) + }, + Abs => { + let mut result = child_answer.value.abs(); + let rounding_change = result - child_answer.value; + if rounding_change == d128!(-0.5) { result += d128!(1); } + return Ok(Answer::new(result, child_answer.unit)) + }, // Sin, // Cos, diff --git a/src/lexer.rs b/src/lexer.rs index cf0440d..8fece60 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -5,7 +5,7 @@ use crate::Operator::{Caret, Divide, LeftParen, Minus, Modulo, Multiply, Plus, R use crate::UnaryOperator::{Percent, Factorial}; use crate::TextOperator::{Of, To}; use crate::Constant::{E, Pi}; -use crate::FunctionIdentifier::{Acos, Acosh, Asin, Asinh, Atan, Atanh, Cbrt, Ceil, Cos, Cosh, Exp, Fabs, Floor, Ln, Log, Round, Sin, Sinh, Sqrt, Tan, Tanh}; +use crate::FunctionIdentifier::{Acos, Acosh, Asin, Asinh, Atan, Atanh, Cbrt, Ceil, Cos, Cosh, Exp, Abs, Floor, Ln, Log, Round, Sin, Sinh, Sqrt, Tan, Tanh}; use crate::units::Unit::*; pub fn lex(input: &str) -> Result { @@ -76,10 +76,10 @@ pub fn lex(input: &str) -> Result { "ln" => tokens.push(Token::FunctionIdentifier(Ln)), "exp" => tokens.push(Token::FunctionIdentifier(Exp)), + "round" | "rint" => tokens.push(Token::FunctionIdentifier(Round)), "ceil" => tokens.push(Token::FunctionIdentifier(Ceil)), "floor" => tokens.push(Token::FunctionIdentifier(Floor)), - "round" | "rint" => tokens.push(Token::FunctionIdentifier(Round)), - "fabs" => tokens.push(Token::FunctionIdentifier(Fabs)), + "abs" | "fabs" => tokens.push(Token::FunctionIdentifier(Abs)), "sin" => tokens.push(Token::FunctionIdentifier(Sin)), "cos" => tokens.push(Token::FunctionIdentifier(Cos)), diff --git a/src/main.rs b/src/main.rs index 9b56295..4076d76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,10 +42,10 @@ pub enum FunctionIdentifier { Ln, Exp, + Round, Ceil, Floor, - Round, - Fabs, + Abs, Sin, Cos,