Skip to content

Commit 84c076f

Browse files
authored
fix(stdlib): Properly handle extremely large integer bases in Number.(**) (#1950)
1 parent 7cdcf95 commit 84c076f

File tree

2 files changed

+11
-11
lines changed

2 files changed

+11
-11
lines changed

compiler/test/stdlib/number.test.gr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ assert 10223372036854775809 ** 10 ==
204204
12472159440978016923768615307032788210916694000775261660538874886865415760948494778813645195039710006678013364969179502650466497057008288260604039903029954443675868581729857084924132550246401
205205
assert 1 ** 9223372036854775809 == 1
206206
assert 2.0 ** 9223372036854775809 == Infinity
207+
assert 2.0 ** 99223372036854775809 == Infinity
207208
assert pow(1/2, 2) == 1/4
208209
assert pow(1/2, 3) == 1/8
209210
assert Number.isRational(pow(1/2, 2))

stdlib/runtime/numbers.gr

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2859,19 +2859,20 @@ provide let (**) = (base, power) => {
28592859
} else {
28602860
// Based on https://git.musl-libc.org/cgit/musl/tree/src/math/pow.c
28612861
from WasmF64 use { (==), (!=), (<=), (/), (*), (+) }
2862-
// Constants
2863-
let infinity = 1.0W / 0.0W
2864-
let nan = 0.0W / 0.0W
28652862
let x = coerceNumberToWasmF64(base)
28662863
let y = coerceNumberToWasmF64(power)
28672864
// Fast paths
28682865
if (WasmF64.abs(y) <= 2.0W) {
28692866
if (y == 2.0W) {
28702867
return WasmI32.toGrain(newFloat64(x * x)): Number
28712868
} else if (y == 0.5W) {
2872-
let output =
2873-
if (x != infinity) WasmF64.abs(WasmF64.sqrt(x)) else infinity
2874-
return WasmI32.toGrain(newFloat64(output)): Number
2869+
if (x != InfinityW) {
2870+
return WasmI32.toGrain(
2871+
newFloat64(WasmF64.abs(WasmF64.sqrt(x)))
2872+
): Number
2873+
} else {
2874+
return Infinity
2875+
}
28752876
} else if (y == -1.0W) {
28762877
return WasmI32.toGrain(newFloat64(1.0W / x)): Number
28772878
} else if (y == 1.0W) {
@@ -3002,9 +3003,7 @@ provide let (**) = (base, power) => {
30023003
let mut s = 1.0W
30033004
if (hx < 0n) {
30043005
if (yisint == 0n) {
3005-
from WasmF64 use { (-) }
3006-
let d = x - x
3007-
return WasmI32.toGrain(newFloat64(d / d)): Number
3006+
return NaN
30083007
} else if (yisint == 1n) s = -1.0W
30093008
}
30103009
let mut t1 = 0.0W
@@ -3022,10 +3021,10 @@ provide let (**) = (base, power) => {
30223021
if (iy > 0x43F00000n) {
30233022
if (ix <= 0x3FEFFFFFn) {
30243023
let output = if (hy < 0n) huge * huge else tiny * tiny
3025-
return WasmI32.toGrain(newFloat64(z)): Number
3024+
return WasmI32.toGrain(newFloat64(output)): Number
30263025
} else if (ix >= 0x3FF00000n) {
30273026
let output = if (hy > 0n) huge * huge else tiny * tiny
3028-
return WasmI32.toGrain(newFloat64(z)): Number
3027+
return WasmI32.toGrain(newFloat64(output)): Number
30293028
}
30303029
}
30313030
if (ix < 0x3FEFFFFFn) {

0 commit comments

Comments
 (0)