big: More ZII refactoring.

This commit is contained in:
Jeroen van Rijn
2021-08-11 20:59:50 +02:00
parent 2e372b33a3
commit d9efa6c8b5
5 changed files with 87 additions and 43 deletions
+16 -11
View File
@@ -10,7 +10,11 @@ package big
*/
log_n_int :: proc(a: ^Int, base: DIGIT) -> (log: int, err: Error) {
assert_initialized(a);
if a == nil {
return 0, .Nil_Pointer_Passed;
} else if !is_initialized(a) {
return 0, .Int_Not_Initialized;
}
if is_neg(a) || is_zero(a) || base < 2 || DIGIT(base) > _DIGIT_MAX {
return -1, .Invalid_Input;
}
@@ -19,14 +23,14 @@ log_n_int :: proc(a: ^Int, base: DIGIT) -> (log: int, err: Error) {
Fast path for bases that are a power of two.
*/
if is_power_of_two(int(base)) {
return _log_power_of_two(a, base), .OK;
return _log_power_of_two(a, base);
}
/*
Fast path for `Int`s that fit within a single `DIGIT`.
*/
if a.used == 1 {
return log_n_digit(a.digit[0], DIGIT(base)), .OK;
return log_n_digit(a.digit[0], DIGIT(base));
}
// if (MP_HAS(S_MP_LOG)) {
@@ -42,14 +46,15 @@ log_n :: proc{log_n_int, log_n_digit};
Returns the log2 of an `Int`, provided `base` is a power of two.
Don't call it if it isn't.
*/
_log_power_of_two :: proc(a: ^Int, base: DIGIT) -> (log: int) {
_log_power_of_two :: proc(a: ^Int, base: DIGIT) -> (log: int, err: Error) {
base := base;
y: int;
for y = 0; base & 1 == 0; {
y += 1;
base >>= 1;
}
return (count_bits(a) - 1) / y;
log, err = count_bits(a);
return (log - 1) / y, err;
}
/*
@@ -69,20 +74,20 @@ small_pow :: proc(base: _WORD, exponent: _WORD) -> (result: _WORD) {
return result;
}
log_n_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int) {
log_n_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
/*
If the number is smaller than the base, it fits within a fraction.
Therefore, we return 0.
*/
if a < base {
return 0;
return 0, .OK;
}
/*
If a number equals the base, the log is 1.
*/
if a == base {
return 1;
return 1, .OK;
}
N := _WORD(a);
@@ -111,13 +116,13 @@ log_n_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int) {
bracket_low = bracket_mid;
}
if N == bracket_mid {
return mid;
return mid, .OK;
}
}
if bracket_high == N {
return high;
return high, .OK;
} else {
return low;
return low, .OK;
}
}