From bf319ea2220ba47082d635972feb007fe1eb54bb Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Wed, 6 Dec 2023 20:20:34 -0500 Subject: [PATCH 1/2] feat(stdlib): Add `**` to `Int64` --- compiler/test/stdlib/int64.test.gr | 28 ++++++++++++++++++++++++ stdlib/int64.gr | 35 ++++++++++++++++++++++++++++++ stdlib/int64.md | 26 ++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/compiler/test/stdlib/int64.test.gr b/compiler/test/stdlib/int64.test.gr index 3e8df632a1..3126589c04 100644 --- a/compiler/test/stdlib/int64.test.gr +++ b/compiler/test/stdlib/int64.test.gr @@ -65,3 +65,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/int64.gr b/stdlib/int64.gr index 02aa9aed97..672f01b5c2 100644 --- a/stdlib/int64.gr +++ b/stdlib/int64.gr @@ -505,3 +505,38 @@ provide let popcnt = (value: Int64) => { let ptr = newInt64(WasmI64.popcnt(nv)) WasmI32.toGrain(ptr): Int64 } + +// 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/int64.md b/stdlib/int64.md index 8b2428dfe2..ae22c37c6c 100644 --- a/stdlib/int64.md +++ b/stdlib/int64.md @@ -880,3 +880,29 @@ Returns: |----|-----------| |`Int64`|The amount of 1-bits in its operand| +### Int64.**(\*\*)** + +
+Added in next +No other changes yet. +
+ +```grain +(**) : (base: Int64, power: Int64) => Int64 +``` + +Computes the exponentiation of the given base and power. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`base`|`Int64`|The base number| +|`power`|`Int64`|The exponent number| + +Returns: + +|type|description| +|----|-----------| +|`Int64`|The base raised to the given power| + From d5f4600aa4bcc54513058635aa5a45ed1f9b08ce Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Sun, 31 Dec 2023 17:10:44 -0500 Subject: [PATCH 2/2] chore: Switch to using new ops --- stdlib/int64.gr | 8 -------- 1 file changed, 8 deletions(-) diff --git a/stdlib/int64.gr b/stdlib/int64.gr index 672f01b5c2..cd95922126 100644 --- a/stdlib/int64.gr +++ b/stdlib/int64.gr @@ -508,11 +508,6 @@ provide let popcnt = (value: Int64) => { // 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) { @@ -534,9 +529,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) }