aboutsummaryrefslogtreecommitdiff
path: root/core/math/big/internal.odin
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-09-03 23:41:14 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-09-03 23:54:54 +0200
commitb1ed7fc6b9bb16540a76d8edf286415f641ae120 (patch)
tree0738ba10f7a3e4ee17dd99a354c9bf4924ed8031 /core/math/big/internal.odin
parente3809f5c1b10963bcdbcebe925f0d3a31c0ea893 (diff)
big: Add Lucas-Selfridge.
Diffstat (limited to 'core/math/big/internal.odin')
-rw-r--r--core/math/big/internal.odin29
1 files changed, 28 insertions, 1 deletions
diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin
index 81cb325d7..5b09e97e2 100644
--- a/core/math/big/internal.odin
+++ b/core/math/big/internal.odin
@@ -545,6 +545,25 @@ internal_int_shl1 :: proc(dest, src: ^Int, allocator := context.allocator) -> (e
}
/*
+ Multiply bigint `a` with int `d` and put the result in `dest`.
+ Like `internal_int_mul_digit` but with an integer as the small input.
+*/
+internal_int_mul_integer :: proc(dest, a: ^Int, b: $T, allocator := context.allocator) -> (err: Error)
+where intrinsics.type_is_integer(T) && T != DIGIT {
+ context.allocator = allocator;
+
+ t := &Int{};
+ defer internal_destroy(t);
+
+ /*
+ DIGIT might be smaller than a long, which excludes the use of `internal_int_mul_digit` here.
+ */
+ internal_set(t, b) or_return;
+ internal_mul(dest, a, t) or_return;
+ return;
+}
+
+/*
Multiply by a DIGIT.
*/
internal_int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT, allocator := context.allocator) -> (err: Error) {
@@ -697,7 +716,7 @@ internal_int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.alloc
return err;
}
-internal_mul :: proc { internal_int_mul, internal_int_mul_digit, };
+internal_mul :: proc { internal_int_mul, internal_int_mul_digit, internal_int_mul_integer };
internal_sqr :: proc (dest, src: ^Int, allocator := context.allocator) -> (res: Error) {
/*
@@ -940,6 +959,14 @@ internal_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
return #force_inline _private_int_gcd_lcm(res_gcd, res_lcm, a, b, allocator);
}
+internal_int_gcd :: proc(res_gcd, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
+ return #force_inline _private_int_gcd_lcm(res_gcd, nil, a, b, allocator);
+}
+
+internal_int_lcm :: proc(res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
+ return #force_inline _private_int_gcd_lcm(nil, res_lcm, a, b, allocator);
+}
+
/*
remainder = numerator % (1 << bits)