Skip to content

Commit 960fadd

Browse files
authored
fix(stdlib): Optimize number modulo (#2144)
1 parent c8624c3 commit 960fadd

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

compiler/test/runtime/numbers.test.gr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ assert isNaN(NaN % Infinity)
8989
assert isNaN(NaN % -Infinity)
9090
assert -17 % 4 == 3
9191
assert -17 % -4 == -1
92-
assert 17 % -4 == 5
92+
assert 17 % -4 == -3
9393
assert -17 % 17 == 0
9494
assert 17 % -17 == 0
9595
assert 17 % 17 == 0

stdlib/runtime/numbers.gr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,7 @@ let i64abs = x => {
16131613

16141614
@unsafe
16151615
let numberMod = (x, y) => {
1616-
use WasmI64.{ (!=), (-), (*), (<), (>) }
1616+
use WasmI64.{ (!=), (-), (*), (<), (>), (^) }
16171617
// incRef x and y to reuse them via WasmI32.toGrain
16181618
Memory.incRef(x)
16191619
Memory.incRef(y)
@@ -1636,14 +1636,14 @@ let numberMod = (x, y) => {
16361636
throw Exception.ModuloByZero
16371637
}
16381638
// We implement true modulo
1639-
if (xval < 0N && yval > 0N || xval > 0N && yval < 0N) {
1640-
let modval = WasmI64.remS(i64abs(xval), i64abs(yval))
1641-
let result = if (modval != 0N) {
1642-
i64abs(yval) - modval * (if (yval < 0N) -1N else 1N)
1643-
} else {
1644-
modval
1645-
}
1646-
reducedInteger(result)
1639+
if ((xval ^ yval) < 0N) {
1640+
let xabs = i64abs(xval)
1641+
let yabs = i64abs(yval)
1642+
let mval = WasmI64.remS(xabs, yabs)
1643+
let mres = yabs - mval
1644+
reducedInteger(
1645+
if (mval != 0N) (if (yval < 0N) 0N - mres else mres) else 0N
1646+
)
16471647
} else {
16481648
reducedInteger(WasmI64.remS(xval, yval))
16491649
}

0 commit comments

Comments
 (0)