diff --git a/src/util/math.ts b/src/util/math.ts index a52d07a4c4..25759f35d1 100644 --- a/src/util/math.ts +++ b/src/util/math.ts @@ -15,7 +15,11 @@ export function accuratePow64(x: f64, y: f64): f64 { // or/and 10 ** -5 != 1e-5 anymore. For avoid this behaviour we are forcing exponent // to fractional form and compensate this afterwards. if (isFinite(y) && Math.abs(y) >= 2 && Math.trunc(y) == y) { - return Math.pow(x, y - 0.5) * Math.pow(x, 0.5); + if (y < 0) { + return Math.pow(x, y + 0.5) / Math.pow(x, 0.5); + } else { + return Math.pow(x, y - 0.5) * Math.pow(x, 0.5); + } } } return Math.pow(x, y); diff --git a/tests/compiler/std/math.debug.wat b/tests/compiler/std/math.debug.wat index 99d9306693..c781f2c6d0 100644 --- a/tests/compiler/std/math.debug.wat +++ b/tests/compiler/std/math.debug.wat @@ -59314,6 +59314,34 @@ unreachable end f64.const 10 + f64.const -308 + call $~lib/math/NativeMath.pow + f64.const 1e-308 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4137 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const -323 + call $~lib/math/NativeMath.pow + f64.const 1e-323 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4138 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 f64.const 208 call $~lib/math/NativeMath.pow f64.const 1.e+208 @@ -59322,7 +59350,91 @@ if i32.const 0 i32.const 32 - i32.const 4137 + i32.const 4139 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const 64 + call $~lib/math/NativeMath.pow + f64.const 1.e+64 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4140 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const -64 + call $~lib/math/NativeMath.pow + f64.const 1e-64 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4141 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const 53 + call $~lib/math/NativeMath.pow + f64.const 1.e+53 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4142 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const -53 + call $~lib/math/NativeMath.pow + f64.const 1e-53 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4143 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const 0 + call $~lib/math/NativeMath.pow + f64.const 1 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4144 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const 5 + call $~lib/math/NativeMath.pow + f64.const 1e5 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4145 i32.const 1 call $~lib/builtins/abort unreachable @@ -59336,7 +59448,35 @@ if i32.const 0 i32.const 32 - i32.const 4138 + i32.const 4146 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const 3 + call $~lib/math/NativeMath.pow + f64.const 1e3 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4147 + i32.const 1 + call $~lib/builtins/abort + unreachable + end + f64.const 10 + f64.const -3 + call $~lib/math/NativeMath.pow + f64.const 0.001 + f64.eq + i32.eqz + if + i32.const 0 + i32.const 32 + i32.const 4148 i32.const 1 call $~lib/builtins/abort unreachable @@ -59350,7 +59490,7 @@ if i32.const 0 i32.const 32 - i32.const 4139 + i32.const 4149 i32.const 1 call $~lib/builtins/abort unreachable @@ -59364,7 +59504,7 @@ if i32.const 0 i32.const 32 - i32.const 4140 + i32.const 4150 i32.const 1 call $~lib/builtins/abort unreachable diff --git a/tests/compiler/std/math.ts b/tests/compiler/std/math.ts index 95eefbbe23..7ed266d6f5 100644 --- a/tests/compiler/std/math.ts +++ b/tests/compiler/std/math.ts @@ -4133,8 +4133,18 @@ assert(0.0 ** 0 == 1.0); assert(1.0 ** 1 == 1.0); // Special cases for test constant fold correctness -assert(10.0 ** 308 == 1e308); -assert(10.0 ** 208 == 1e208); +assert(10.0 ** +308 == 1e+308); +assert(10.0 ** -308 == 1e-308); +assert(10.0 ** -323 == 1e-323); +assert(10.0 ** +208 == 1e+208); +assert(10.0 ** +64 == 1e+64); +assert(10.0 ** -64 == 1e-64); +assert(10.0 ** +53 == 1e+53); +assert(10.0 ** -53 == 1e-53); +assert(10.0 ** 0 == 1e+0); +assert(10.0 ** +5 == 1e+5); assert(10.0 ** -5 == 1e-5); +assert(10.0 ** +3 == 1e+3); +assert(10.0 ** -3 == 1e-3); assert(f32(10) ** 38 == f32(1e38)); assert(f32(10) ** -5 == f32(1e-5));