Fix power function to return a result

This commit is contained in:
Mikko Ahlroth 2024-02-15 21:33:14 +02:00
parent ba4db93f50
commit 7545b2aaf8
6 changed files with 36 additions and 9 deletions

View file

@ -1,3 +1,9 @@
2.0.0
-----
* The power function was changed to return a result to prevent calling it with
a negative exponent.
1.0.0 1.0.0
----- -----

View file

@ -40,7 +40,7 @@ pub fn main() {
bigi.from_int(65_535) bigi.from_int(65_535)
) )
// 1001764965203423232489536175780127875223912737784875709632508486855447029778... // Ok(1001764965203423232489536175780127875223912737784875709632508486855447029778...)
} }
``` ```

View file

@ -109,9 +109,11 @@ pub fn modulo_no_zero(
) -> Result(BigInt, Nil) ) -> Result(BigInt, Nil)
/// Raise the base to the exponent. /// Raise the base to the exponent.
///
/// If the exponent is negative, an error is returned.
@external(erlang, "bigi_ffi", "power") @external(erlang, "bigi_ffi", "power")
@external(javascript, "./bigi_ffi.mjs", "power") @external(javascript, "./bigi_ffi.mjs", "power")
pub fn power(base a: BigInt, exponent b: BigInt) -> BigInt pub fn power(base a: BigInt, exponent b: BigInt) -> Result(BigInt, Nil)
/// Get the digits in a given bigint as a list of integers. /// Get the digits in a given bigint as a list of integers.
/// ///

View file

@ -51,12 +51,15 @@ modulo(A, B) -> ((A rem B) + B) rem B.
modulo_no_zero(_, 0) -> {error, nil}; modulo_no_zero(_, 0) -> {error, nil};
modulo_no_zero(A, B) -> {ok, modulo(A, B)}. modulo_no_zero(A, B) -> {ok, modulo(A, B)}.
power(_, 0) -> power(_, Exp) when Exp < 0 -> {error, nil};
power(Base, Exp) -> {ok, do_power(Base, Exp)}.
do_power(_, 0) ->
1; 1;
power(A, 1) -> do_power(A, 1) ->
A; A;
power(A, N) -> do_power(A, N) ->
B = power(A, N div 2), B = do_power(A, N div 2),
B * B * B * B *
(case N rem 2 of (case N rem 2 of
0 -> 1; 0 -> 1;

View file

@ -100,5 +100,9 @@ export function modulo_no_zero(a, b) {
} }
export function power(a, b) { export function power(a, b) {
return a ** b; if (b < 0) {
return new Error(undefined);
}
return new Ok(a ** b);
} }

File diff suppressed because one or more lines are too long