diff options
| author | HarmoGlace <23212967+HarmoGlace@users.noreply.github.com> | 2023-04-04 14:33:26 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-04 14:33:26 +0200 |
| commit | 4aa5e0a4a3d005c25cbd12c843e464a791340c1a (patch) | |
| tree | fd7daa485692eadd65a67e771cd2d71fcf6dc332 /library | |
| parent | 2d1598e51d10bfe4e331c1ad6ca7899c5cdbb468 (diff) | |
Make behavior of calculation functions consistent (#515)
Diffstat (limited to 'library')
| -rw-r--r-- | library/src/compute/calc.rs | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/library/src/compute/calc.rs b/library/src/compute/calc.rs index ccc6e7b1..c48c6816 100644 --- a/library/src/compute/calc.rs +++ b/library/src/compute/calc.rs @@ -104,11 +104,23 @@ pub fn pow( _ => {} }; - match (base, exp) { + let return_value = match (base, exp) { (Num::Int(a), Num::Int(b)) if b >= 0 => Value::Int(a.pow(b as u32)), (a, Num::Int(b)) => Value::Float(a.float().powi(b as i32)), (a, b) => Value::Float(a.float().powf(b.float())), + }; + + let is_nan = match return_value { + Value::Float(f) => f.is_nan(), + Value::Int(i) => (i as f64).is_nan(), + _ => false, + }; + + if is_nan { + bail!(span, "the return value is not a real number") } + + return_value } /// Calculate the square root of a number. @@ -367,20 +379,35 @@ pub fn tanh( /// Returns: float #[func] pub fn log( - /// The number whose logarithm to calculate. - value: f64, - /// The base of the logarithm. + /// The number whose logarithm to calculate. It must be strictly positive. + value: Spanned<Num>, + /// The base of the logarithm. It can't be null. #[named] #[default(10.0)] base: f64, ) -> Value { - Value::Float(if base == 2.0 { - value.log2() + let number = value.v.float(); + + if number <= 0 as f64 { + bail!(value.span, "a logarithm parameter must be strictly positive") + } + if !base.is_normal() { + bail!(value.span, "a logarithm base should be normal (not NaN, not infinite, non-null, not subnormal)") + } + + let return_value = if base == 2.0 { + number.log2() } else if base == 10.0 { - value.log10() + number.log10() } else { - value.log(base) - }) + number.log(base) + }; + + if return_value.is_infinite() || return_value.is_nan() { + bail!(value.span, "this logarithm doesn't return a real value") + } + + Value::Float(return_value) } /// Round a number down to the nearest integer. |
