aboutsummaryrefslogtreecommitdiff
path: root/core/math/big/internal.odin
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-08-13 14:55:53 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-08-13 14:55:53 +0200
commit37be8d40912a2fbf118efffdcf357aa68b78ec08 (patch)
tree58cb22ad60263ca4d22fc6a2256b1e9ce2fef2d9 /core/math/big/internal.odin
parentf72a0de0740d1f6146251ab3e3b7fa55b180826f (diff)
big: Add `internal_invmod`.
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 695dca04d..6610c8429 100644
--- a/core/math/big/internal.odin
+++ b/core/math/big/internal.odin
@@ -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;