From e084bafed7180a5b89aede3f1b64897ca292cc54 Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Wed, 6 Dec 2023 20:26:37 -0500 Subject: [PATCH 1/2] feat(stdlib): Add `**` to `Int32` --- compiler/test/stdlib/int32.test.gr | 28 ++++++++++++++++++++++++ stdlib/int32.gr | 35 ++++++++++++++++++++++++++++++ stdlib/int32.md | 26 ++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/compiler/test/stdlib/int32.test.gr b/compiler/test/stdlib/int32.test.gr index 6cf586e7c0..fd77723723 100644 --- a/compiler/test/stdlib/int32.test.gr +++ b/compiler/test/stdlib/int32.test.gr @@ -67,3 +67,31 @@ from Pervasives use { (==) } // Regression #1339 let arr = [> 1, 2, 3] assert arr[toNumber(1l)] == 2 + +// pow +assert 0l ** 3l == 0l +assert 0l ** 2l == 0l +assert 0l ** 1l == 0l +assert 0l ** 0l == 1l +assert 1l ** 0l == 1l +assert -1l ** 0l == 1l +assert 1l ** 1l == 1l +assert 2l ** 1l == 2l +assert 300l ** 1l == 300l +assert -1l ** 1l == -1l +assert -2l ** 1l == -2l +assert -300l ** 1l == -300l +assert 0l ** 1l == 0l +assert 1l ** 0l == 1l +assert 0l ** 0l == 1l +assert 1l ** 5l == 1l +assert 5l ** 5l == 3125l +assert -5l ** 5l == -3125l +assert 5l ** 6l == 15625l +assert -5l ** 6l == 15625l +assert 1l ** 1l == 1l +assert 2l ** 1l == 2l +assert 300l ** 1l == 300l +assert -1l ** 1l == -1l +assert -2l ** 1l == -2l +assert -300l ** 1l == -300l diff --git a/stdlib/int32.gr b/stdlib/int32.gr index eca431fbc3..94deb036b5 100644 --- a/stdlib/int32.gr +++ b/stdlib/int32.gr @@ -518,3 +518,38 @@ provide let popcnt = (value: Int32) => { let ptr = newInt32(WasmI32.popcnt(nv)) WasmI32.toGrain(ptr): Int32 } + +// Exponentiation by squaring https://en.wikipedia.org/wiki/Exponentiation_by_squaring special path for int^int +let rec expBySquaring = (y, x, n) => { + let (==) = eq + let (*) = mul + let (%) = mod + let (/) = div + let (-) = sub + if (n == 0l) { + 1l + } else if (n == 1l) { + x * y + } else if (n % 2l == 0l) { + expBySquaring(y, x * x, n / 2l) + } else { + expBySquaring(x * y, x * x, (n - 1l) / 2l) + } +} + +/** + * Computes the exponentiation of the given base and power. + * + * @param base: The base number + * @param power: The exponent number + * @returns The base raised to the given power + * + * @since v0.6.0 + */ +provide let (**) = (base, power) => { + let (<) = lt + let (/) = div + let (*) = mul + if (power < 0l) return expBySquaring(1l, 1l / base, power * -1l) + else return expBySquaring(1l, base, power) +} diff --git a/stdlib/int32.md b/stdlib/int32.md index 3059ded1d7..b728fe19c3 100644 --- a/stdlib/int32.md +++ b/stdlib/int32.md @@ -880,3 +880,29 @@ Returns: |----|-----------| |`Int32`|The amount of 1-bits in its operand| +### Int32.**(\*\*)** + +
+Added in next +No other changes yet. +
+ +```grain +(**) : (base: Int32, power: Int32) => Int32 +``` + +Computes the exponentiation of the given base and power. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`base`|`Int32`|The base number| +|`power`|`Int32`|The exponent number| + +Returns: + +|type|description| +|----|-----------| +|`Int32`|The base raised to the given power| + From d539b899038e53a317a90fd3c2985a8ac797e986 Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Sun, 31 Dec 2023 17:10:00 -0500 Subject: [PATCH 2/2] chore: Switch to using the new ops --- stdlib/int32.gr | 8 -------- 1 file changed, 8 deletions(-) diff --git a/stdlib/int32.gr b/stdlib/int32.gr index 94deb036b5..703955d009 100644 --- a/stdlib/int32.gr +++ b/stdlib/int32.gr @@ -521,11 +521,6 @@ provide let popcnt = (value: Int32) => { // Exponentiation by squaring https://en.wikipedia.org/wiki/Exponentiation_by_squaring special path for int^int let rec expBySquaring = (y, x, n) => { - let (==) = eq - let (*) = mul - let (%) = mod - let (/) = div - let (-) = sub if (n == 0l) { 1l } else if (n == 1l) { @@ -547,9 +542,6 @@ let rec expBySquaring = (y, x, n) => { * @since v0.6.0 */ provide let (**) = (base, power) => { - let (<) = lt - let (/) = div - let (*) = mul if (power < 0l) return expBySquaring(1l, 1l / base, power * -1l) else return expBySquaring(1l, base, power) }