diff --git a/README.md b/README.md index 9682dc0..9dc5326 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,7 @@ Symmetrically, the `EmptyContextWithBuiltinFunctions` has builtin functions enab | `math::sqrt` | 1 | Numeric | Returns the square root of a number. Returns NaN for a negative number | | `math::cbrt` | 1 | Numeric | Returns the cube root of a number | | `math::hypot` | 2 | Numeric | Calculates the length of the hypotenuse of a right-angle triangle given legs of length given by the two arguments | +| `math::abs` | 1 | Numeric | Returns the absolute value of a number, returning an integer if the argument was an integer, and a float otherwise | | `str::regex_matches` | 2 | String, String | Returns true if the first argument matches the regex in the second argument (Requires `regex_support` feature flag) | | `str::regex_replace` | 3 | String, String, String | Returns the first argument with all matches of the regex in the second argument replaced by the third argument (Requires `regex_support` feature flag) | | `str::to_lowercase` | 1 | String | Returns the lower-case version of the string | diff --git a/src/function/builtin.rs b/src/function/builtin.rs index 350a810..7105743 100644 --- a/src/function/builtin.rs +++ b/src/function/builtin.rs @@ -87,6 +87,12 @@ pub fn builtin_function(identifier: &str) -> Option { "math::is_finite" => float_is(FloatType::is_finite), "math::is_infinite" => float_is(FloatType::is_infinite), "math::is_normal" => float_is(FloatType::is_normal), + // Absolute + "math::abs" => Some(Function::new(|argument| match argument { + Value::Float(num) => Ok(Value::Float(num.abs())), + Value::Int(num) => Ok(Value::Int(num.abs())), + _ => Err(EvalexprError::expected_number(argument.clone())), + })), // Other "typeof" => Some(Function::new(move |argument| { Ok(match argument { diff --git a/src/lib.rs b/src/lib.rs index 673443b..cd28209 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -371,6 +371,7 @@ //! | `math::sqrt` | 1 | Numeric | Returns the square root of a number. Returns NaN for a negative number | //! | `math::cbrt` | 1 | Numeric | Returns the cube root of a number | //! | `math::hypot` | 2 | Numeric | Calculates the length of the hypotenuse of a right-angle triangle given legs of length given by the two arguments | +//! | `math::abs` | 1 | Numeric | Returns the absolute value of a number, returning an integer if the argument was an integer, and a float otherwise | //! | `str::regex_matches` | 2 | String, String | Returns true if the first argument matches the regex in the second argument (Requires `regex_support` feature flag) | //! | `str::regex_replace` | 3 | String, String, String | Returns the first argument with all matches of the regex in the second argument replaced by the third argument (Requires `regex_support` feature flag) | //! | `str::to_lowercase` | 1 | String | Returns the lower-case version of the string | diff --git a/tests/integration.rs b/tests/integration.rs index c837fa2..0c97576 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -384,6 +384,11 @@ fn test_builtin_functions() { assert_eq!(eval("math::is_infinite(1.0/0.0)"), Ok(Value::Boolean(true))); assert_eq!(eval("math::is_normal(1.0/0.0)"), Ok(Value::Boolean(false))); assert_eq!(eval("math::is_normal(0)"), Ok(Value::Boolean(false))); + // Absolute + assert_eq!(eval("math::abs(15.4)"), Ok(Value::Float(15.4))); + assert_eq!(eval("math::abs(-15.4)"), Ok(Value::Float(15.4))); + assert_eq!(eval("math::abs(15)"), Ok(Value::Int(15))); + assert_eq!(eval("math::abs(-15)"), Ok(Value::Int(15))); // Other assert_eq!(eval("typeof(4.0, 3)"), Ok(Value::String("tuple".into()))); assert_eq!(eval("typeof(4.0)"), Ok(Value::String("float".into())));