Fix zero power (#511)

This commit is contained in:
HarmoGlace 2023-04-01 19:45:44 +02:00 committed by GitHub
parent 10a3fbd174
commit f94bc9a13f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -90,19 +90,26 @@ pub fn pow(
/// The exponent of the power. Must be non-negative. /// The exponent of the power. Must be non-negative.
exponent: Spanned<Num>, exponent: Spanned<Num>,
) -> Value { ) -> Value {
let exponent = match exponent.v { let exponent_value = match exponent.v {
Num::Int(i) if i > u32::MAX as i64 => { Num::Int(i) if i > u32::MAX as i64 => {
bail!(exponent.span, "exponent too large"); bail!(exponent.span, "exponent too large");
} }
Num::Int(i) if i != 0 => exponent.v, Num::Int(i) => exponent.v,
Num::Float(f) if f.is_normal() => exponent.v, Num::Float(f) if f.is_normal() || f == 0 as f64 => exponent.v,
_ => { _ => {
bail!(exponent.span, "exponent must be normal (non-zero, non-NaN, non-infinite, non-subnormal)"); bail!(
exponent.span,
"exponent must be normal (non-NaN, non-infinite, non-subnormal)"
);
} }
}; };
match (base, exponent) { if exponent_value.float() == 0 as f64 && base.float() == 0 as f64 {
(Num::Int(a), Num::Int(b)) if b > 0 => Value::Int(a.pow(b as u32)), return bail!(exponent.span, "zero to the power of zero is undefined");
}
match (base, exponent_value) {
(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, Num::Int(b)) => Value::Float(a.float().powi(b as i32)),
(a, b) => Value::Float(f64::powf(a.float(), b.float())), (a, b) => Value::Float(f64::powf(a.float(), b.float())),
} }