big: Add Lucas-Selfridge.

This commit is contained in:
Jeroen van Rijn
2021-09-03 23:54:54 +02:00
parent e3809f5c1b
commit b1ed7fc6b9
4 changed files with 274 additions and 16 deletions
+28 -1
View File
@@ -544,6 +544,25 @@ internal_int_shl1 :: proc(dest, src: ^Int, allocator := context.allocator) -> (e
return internal_clamp(dest);
}
/*
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.
*/
@@ -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)