From 32b9639be58408d587f9c9c29a4b56857e6f328f Mon Sep 17 00:00:00 2001 From: Spotandjake <40705786+spotandjake@users.noreply.github.com> Date: Sun, 31 Dec 2023 18:13:07 -0500 Subject: [PATCH] feat(stdlib): Add `**` operator to `Int32` module (#1938) --- compiler/test/stdlib/int32.test.gr | 28 ++++++++++++++++++++++++++++ stdlib/int32.gr | 27 +++++++++++++++++++++++++++ stdlib/int32.md | 26 ++++++++++++++++++++++++++ 3 files changed, 81 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..703955d009 100644 --- a/stdlib/int32.gr +++ b/stdlib/int32.gr @@ -518,3 +518,30 @@ 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) => { + 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) => { + 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| +