Skip to content

Commit 67bee5c

Browse files
feat(stdlib)!: Add optimization for Number.pow(Rational, Int) (#1716)
* feat!: Add Optimization for `Rationional^Int` * Update stdlib/runtime/numbers.gr --------- Co-authored-by: Oscar Spencer <oscar.spen@gmail.com>
1 parent 3c86e45 commit 67bee5c

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

compiler/test/stdlib/number.test.gr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ assert Number.pow(10223372036854775809, 10) ==
217217
12472159440978016923768615307032788210916694000775261660538874886865415760948494778813645195039710006678013364969179502650466497057008288260604039903029954443675868581729857084924132550246401
218218
assert Number.pow(1, 9223372036854775809) == 1
219219
assert Number.pow(2.0, 9223372036854775809) == Infinity
220+
assert Number.pow(1/2, 2) == 1/4
221+
assert Number.pow(1/2, 3) == 1/8
222+
assert Number.isRational(Number.pow(1/2, 2))
223+
assert Number.isRational(Number.pow(1/2, 3))
224+
assert Number.pow(1/2, -2) == 4
220225
// exp
221226
assert Number.exp(1) == 2.718281828459045
222227
assert Number.exp(10) == 22026.465794806703

stdlib/runtime/numbers.gr

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,13 +2803,30 @@ let rec expBySquaring = (y, x, n) => {
28032803
provide let (**) = (base, power) => {
28042804
let (==) = numberEq
28052805
let (!=) = (x, y) => !numberEq(x, y)
2806+
let basePtr = WasmI32.fromGrain(base)
2807+
let powerPtr = WasmI32.fromGrain(power)
28062808
if (base == 1 && power != 0) {
28072809
return 1
2808-
} else if (
2809-
isInteger(WasmI32.fromGrain(base)) && isInteger(WasmI32.fromGrain(power))
2810-
) {
2810+
} else if (isInteger(basePtr) && isInteger(powerPtr)) {
28112811
if (power < 0) return expBySquaring(1, 1 / base, power * -1)
28122812
else return expBySquaring(1, base, power)
2813+
} else if (isRational(basePtr) && isInteger(powerPtr)) {
2814+
// Apply expBySquaring to numerator and denominator
2815+
let numerator = WasmI32.fromGrain(base)
2816+
Memory.incRef(numerator)
2817+
let numerator = WasmI32.toGrain(numerator): Rational
2818+
let numerator = rationalNumerator(numerator)
2819+
let denominator = WasmI32.fromGrain(base)
2820+
Memory.incRef(denominator)
2821+
let denominator = WasmI32.toGrain(denominator): Rational
2822+
let denominator = rationalDenominator(denominator)
2823+
let numerator =
2824+
if (power < 0) expBySquaring(1, 1 / numerator, power * -1)
2825+
else expBySquaring(1, numerator, power)
2826+
let denominator =
2827+
if (power < 0) expBySquaring(1, 1 / denominator, power * -1)
2828+
else expBySquaring(1, denominator, power)
2829+
return numerator / denominator
28132830
} else {
28142831
// Based on https://git.musl-libc.org/cgit/musl/tree/src/math/pow.c
28152832
from WasmF64 use {

0 commit comments

Comments
 (0)