mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-29 17:34:34 +00:00
big: Add internal_invmod.
This commit is contained in:
@@ -1740,6 +1740,29 @@ internal_int_neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (er
|
||||
}
|
||||
internal_neg :: proc { internal_int_neg, };
|
||||
|
||||
/*
|
||||
hac 14.61, pp608.
|
||||
*/
|
||||
internal_int_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
|
||||
context.allocator = allocator;
|
||||
/*
|
||||
For all n in N and n > 0, n = 0 mod 1.
|
||||
*/
|
||||
if internal_is_positive(a) && internal_cmp(b, 1) == 0 { return internal_zero(dest); }
|
||||
|
||||
/*
|
||||
`b` cannot be negative and has to be > 1
|
||||
*/
|
||||
if internal_is_negative(b) && internal_cmp(b, 1) != 1 { return .Invalid_Argument; }
|
||||
|
||||
/*
|
||||
If the modulus is odd we can use a faster routine instead.
|
||||
*/
|
||||
if internal_is_odd(b) { return _private_inverse_modulo_odd(dest, a, b); }
|
||||
|
||||
return _private_inverse_modulo(dest, a, b);
|
||||
}
|
||||
internal_invmod :: proc{ internal_int_inverse_modulo, };
|
||||
|
||||
/*
|
||||
Helpers to extract values from the `Int`.
|
||||
@@ -1991,7 +2014,11 @@ internal_int_get :: proc(a: ^Int, $T: typeid) -> (res: T, err: Error) where intr
|
||||
internal_get :: proc { internal_int_get, };
|
||||
|
||||
internal_int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) {
|
||||
l := min(a.used, 17); // log2(max(f64)) is approximately 1020, or 17 legs.
|
||||
/*
|
||||
log2(max(f64)) is approximately 1020, or 17 legs with the 64-bit storage.
|
||||
*/
|
||||
legs :: 1020 / _DIGIT_BITS;
|
||||
l := min(a.used, legs);
|
||||
fac := f64(1 << _DIGIT_BITS);
|
||||
d := 0.0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user