diff --git a/core/engine/src/builtins/math/mod.rs b/core/engine/src/builtins/math/mod.rs index 424aed1e2d..f33e1f336c 100644 --- a/core/engine/src/builtins/math/mod.rs +++ b/core/engine/src/builtins/math/mod.rs @@ -703,12 +703,29 @@ impl Math { // 2. Set exponent to ? ToNumber(exponent). let y = args.get_or_undefined(1).to_number(context)?; - // 3. If |x| = 1 and the exponent is infinite, return NaN. + // 3. Return Number::exponentiate(base, exponent). + + // https://github.com/rust-lang/rust/issues/60468 + + // https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-exponentiate + // 6.1.6.1.3 Number::exponentiate ( base, exponent ) + // 1. If exponent is NaN, return NaN. + if y.is_nan() { + return Ok(f64::NAN.into()); + } + + // 9. If exponent is +∞𝔽, then + // a. If abs(ℝ(base)) > 1, return +∞𝔽. + // b. If abs(ℝ(base)) = 1, return NaN. + // c. If abs(ℝ(base)) < 1, return +0𝔽. + // 10. If exponent is -∞𝔽, then + // a. If abs(ℝ(base)) > 1, return +0𝔽. + // b. If abs(ℝ(base)) = 1, return NaN. + // c. If abs(ℝ(base)) < 1, return +∞𝔽. if f64::abs(x) == 1f64 && y.is_infinite() { return Ok(f64::NAN.into()); } - // 4. Return ! Number::exponentiate(base, exponent). Ok(x.powf(y).into()) } diff --git a/core/engine/src/builtins/math/tests.rs b/core/engine/src/builtins/math/tests.rs index b85c514162..d0622b4317 100644 --- a/core/engine/src/builtins/math/tests.rs +++ b/core/engine/src/builtins/math/tests.rs @@ -250,6 +250,11 @@ fn pow() { TestAction::assert_eq("Math.pow(-7, 2)", 49.0), TestAction::assert_eq("Math.pow(4, 0.5)", 2.0), TestAction::assert_eq("Math.pow(7, -2)", 0.020_408_163_265_306_12), + TestAction::assert_eq("Math.pow(1, NaN)", f64::NAN), + TestAction::assert_eq("Math.pow(1, Infinity)", f64::NAN), + TestAction::assert_eq("Math.pow(1, -Infinity)", f64::NAN), + TestAction::assert_eq("Math.pow(-1, Infinity)", f64::NAN), + TestAction::assert_eq("Math.pow(-1, -Infinity)", f64::NAN), ]); }