big: Error.None -> nil

This commit is contained in:
Jeroen van Rijn
2021-08-03 17:07:25 +02:00
parent 627872db97
commit 97d80d03f9
9 changed files with 368 additions and 359 deletions

View File

@@ -25,9 +25,9 @@ import "core:intrinsics"
*/
int_add :: proc(dest, a, b: ^Int) -> (err: Error) {
dest := dest; x := a; y := b;
if err = clear_if_uninitialized(x); err != .None { return err; }
if err = clear_if_uninitialized(y); err != .None { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; }
if err = clear_if_uninitialized(x); err != nil { return err; }
if err = clear_if_uninitialized(y); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != nil { return err; }
/*
All parameters have been initialized.
We can now safely ignore errors from comparison routines.
@@ -62,13 +62,13 @@ int_add :: proc(dest, a, b: ^Int) -> (err: Error) {
*/
int_add_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
dest := dest; digit := digit;
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return err;
}
/*
Grow destination as required.
*/
if err = grow(dest, a.used + 1); err != .None {
if err = grow(dest, a.used + 1); err != nil {
return err;
}
@@ -110,7 +110,7 @@ int_add_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
/*
dest = |a| - digit
*/
if err = sub(dest, a, digit); err != .None {
if err = sub(dest, a, digit); err != nil {
/*
Restore a's sign.
*/
@@ -186,13 +186,13 @@ int_add_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
*/
int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
dest := dest; x := number; y := decrease;
if err = clear_if_uninitialized(dest); err != .None {
if err = clear_if_uninitialized(dest); err != nil {
return err;
}
if err = clear_if_uninitialized(x); err != .None {
if err = clear_if_uninitialized(x); err != nil {
return err;
}
if err = clear_if_uninitialized(y); err != .None {
if err = clear_if_uninitialized(y); err != nil {
return err;
}
/*
@@ -242,14 +242,14 @@ int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
*/
int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
dest := dest; digit := digit;
if err = clear_if_uninitialized(dest); err != .None {
if err = clear_if_uninitialized(dest); err != nil {
return err;
}
/*
Grow destination as required.
*/
if dest != a {
if err = grow(dest, a.used + 1); err != .None {
if err = grow(dest, a.used + 1); err != nil {
return err;
}
}
@@ -267,14 +267,14 @@ int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
*/
if n, _ := is_neg(dest); n && (dest.digit[0] + digit < _DIGIT_MAX) {
dest.digit[0] += digit;
return .None;
return nil;
}
/*
Can be subtracted from dest.digit[0] without underflow.
*/
if p, _ := is_pos(a); p && (dest.digit[0] > digit) {
dest.digit[0] -= digit;
return .None;
return nil;
}
}
@@ -339,14 +339,14 @@ int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
*/
int_halve :: proc(dest, src: ^Int) -> (err: Error) {
dest := dest; src := src;
if err = clear_if_uninitialized(dest); err != .None {
if err = clear_if_uninitialized(dest); err != nil {
return err;
}
/*
Grow destination as required.
*/
if dest != src {
if err = grow(dest, src.used); err != .None {
if err = grow(dest, src.used); err != nil {
return err;
}
}
@@ -397,14 +397,14 @@ shr1 :: halve;
*/
int_double :: proc(dest, src: ^Int) -> (err: Error) {
dest := dest; src := src;
if err = clear_if_uninitialized(dest); err != .None {
if err = clear_if_uninitialized(dest); err != nil {
return err;
}
/*
Grow destination as required.
*/
if dest != src {
if err = grow(dest, src.used + 1); err != .None {
if err = grow(dest, src.used + 1); err != nil {
return err;
}
}
@@ -462,8 +462,8 @@ shl1 :: double;
remainder = numerator % (1 << bits)
*/
int_mod_bits :: proc(remainder, numerator: ^Int, bits: int) -> (err: Error) {
if err = clear_if_uninitialized(remainder); err != .None { return err; }
if err = clear_if_uninitialized(numerator); err != .None { return err; }
if err = clear_if_uninitialized(remainder); err != nil { return err; }
if err = clear_if_uninitialized(numerator); err != nil { return err; }
if bits < 0 { return .Invalid_Argument; }
if bits == 0 { return zero(remainder); }
@@ -472,7 +472,7 @@ int_mod_bits :: proc(remainder, numerator: ^Int, bits: int) -> (err: Error) {
If the modulus is larger than the value, return the value.
*/
err = copy(remainder, numerator);
if bits >= (numerator.used * _DIGIT_BITS) || err != .None {
if bits >= (numerator.used * _DIGIT_BITS) || err != nil {
return;
}
@@ -499,7 +499,7 @@ mod_bits :: proc { int_mod_bits, };
Multiply by a DIGIT.
*/
int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT) -> (err: Error) {
if err = clear_if_uninitialized(src, dest); err != .None { return err; }
if err = clear_if_uninitialized(src, dest); err != nil { return err; }
if multiplier == 0 {
return zero(dest);
@@ -516,14 +516,14 @@ int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT) -> (err: Error) {
}
if is_power_of_two(int(multiplier)) {
ix: int;
if ix, err = log(multiplier, 2); err != .None { return err; }
if ix, err = log(multiplier, 2); err != nil { return err; }
return shl(dest, src, ix);
}
/*
Ensure `dest` is big enough to hold `src` * `multiplier`.
*/
if err = grow(dest, max(src.used + 1, _DEFAULT_DIGIT_COUNT)); err != .None { return err; }
if err = grow(dest, max(src.used + 1, _DEFAULT_DIGIT_COUNT)); err != nil { return err; }
/*
Save the original used count.
@@ -575,7 +575,7 @@ int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT) -> (err: Error) {
High level multiplication (handles sign).
*/
int_mul :: proc(dest, src, multiplier: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(dest, src, multiplier); err != .None { return err; }
if err = clear_if_uninitialized(dest, src, multiplier); err != nil { return err; }
/*
Early out for `multiplier` is zero; Set `dest` to zero.
@@ -657,10 +657,10 @@ int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: E
/*
Early out if neither of the results is wanted.
*/
if quotient == nil && remainder == nil { return .None; }
if quotient == nil && remainder == nil { return nil; }
if err = clear_if_uninitialized(numerator); err != .None { return err; }
if err = clear_if_uninitialized(denominator); err != .None { return err; }
if err = clear_if_uninitialized(numerator); err != nil { return err; }
if err = clear_if_uninitialized(denominator); err != nil { return err; }
z: bool;
if z, err = is_zero(denominator); z { return .Division_by_Zero; }
@@ -671,12 +671,12 @@ int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: E
c: int;
if c, err = cmp_mag(numerator, denominator); c == -1 {
if remainder != nil {
if err = copy(remainder, numerator); err != .None { return err; }
if err = copy(remainder, numerator); err != nil { return err; }
}
if quotient != nil {
zero(quotient);
}
return .None;
return nil;
}
if false && (denominator.used > 2 * _MUL_KARATSUBA_CUTOFF) && (denominator.used <= (numerator.used/3) * 2) {
@@ -702,10 +702,10 @@ div :: proc { int_div, };
denominator < remainder <= 0 if denominator < 0
*/
int_mod :: proc(remainder, numerator, denominator: ^Int) -> (err: Error) {
if err = divmod(nil, remainder, numerator, denominator); err != .None { return err; }
if err = divmod(nil, remainder, numerator, denominator); err != nil { return err; }
z: bool;
if z, err = is_zero(remainder); z || denominator.sign == remainder.sign { return .None; }
if z, err = is_zero(remainder); z || denominator.sign == remainder.sign { return nil; }
return add(remainder, remainder, numerator);
}
mod :: proc { int_mod, };
@@ -714,7 +714,7 @@ mod :: proc { int_mod, };
remainder = (number + addend) % modulus.
*/
int_addmod :: proc(remainder, number, addend, modulus: ^Int) -> (err: Error) {
if err = add(remainder, number, addend); err != .None { return err; }
if err = add(remainder, number, addend); err != nil { return err; }
return mod(remainder, remainder, modulus);
}
addmod :: proc { int_addmod, };
@@ -723,7 +723,7 @@ addmod :: proc { int_addmod, };
remainder = (number - decrease) % modulus.
*/
int_submod :: proc(remainder, number, decrease, modulus: ^Int) -> (err: Error) {
if err = add(remainder, number, decrease); err != .None { return err; }
if err = add(remainder, number, decrease); err != nil { return err; }
return mod(remainder, remainder, modulus);
}
submod :: proc { int_submod, };
@@ -732,7 +732,7 @@ submod :: proc { int_submod, };
remainder = (number * multiplicand) % modulus.
*/
int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int) -> (err: Error) {
if err = mul(remainder, number, multiplicand); err != .None { return err; }
if err = mul(remainder, number, multiplicand); err != nil { return err; }
return mod(remainder, remainder, modulus);
}
mulmod :: proc { int_mulmod, };
@@ -741,7 +741,7 @@ mulmod :: proc { int_mulmod, };
remainder = (number * number) % modulus.
*/
int_sqrmod :: proc(remainder, number, modulus: ^Int) -> (err: Error) {
if err = sqr(remainder, number); err != .None { return err; }
if err = sqr(remainder, number); err != nil { return err; }
return mod(remainder, remainder, modulus);
}
sqrmod :: proc { int_sqrmod, };
@@ -762,13 +762,13 @@ int_factorial :: proc(res: ^Int, n: DIGIT) -> (err: Error) {
return int_factorial_binary_split(res, n);
}
if err = set(res, _factorial_table[i - 1]); err != .None { return err; }
if err = set(res, _factorial_table[i - 1]); err != nil { return err; }
for {
if err = mul(res, res, DIGIT(i)); err != .None || i == n { return err; }
if err = mul(res, res, DIGIT(i)); err != nil || i == n { return err; }
i += 1;
}
return .None;
return nil;
}
_int_recursive_product :: proc(res: ^Int, start, stop: DIGIT, level := int(0)) -> (err: Error) {
@@ -779,15 +779,15 @@ _int_recursive_product :: proc(res: ^Int, start, stop: DIGIT, level := int(0)) -
num_factors := (stop - start) >> 1;
if num_factors == 2 {
if err = set(t1, start); err != .None { return err; }
if err = add(t2, t1, 2); err != .None { return err; }
if err = set(t1, start); err != nil { return err; }
if err = add(t2, t1, 2); err != nil { return err; }
return mul(res, t1, t2);
}
if num_factors > 1 {
mid := (start + num_factors) | 1;
if err = _int_recursive_product(t1, start, mid, level + 1); err != .None { return err; }
if err = _int_recursive_product(t2, mid, stop, level + 1); err != .None { return err; }
if err = _int_recursive_product(t1, start, mid, level + 1); err != nil { return err; }
if err = _int_recursive_product(t2, mid, stop, level + 1); err != nil { return err; }
return mul(res, t1, t2);
}
@@ -805,17 +805,17 @@ int_factorial_binary_split :: proc(res: ^Int, n: DIGIT) -> (err: Error) {
inner, outer, start, stop, temp := &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
defer destroy(inner, outer, start, stop, temp);
if err = one(inner); err != .None { return err; }
if err = one(outer); err != .None { return err; }
if err = one(inner); err != nil { return err; }
if err = one(outer); err != nil { return err; }
bits_used := int(_DIGIT_TYPE_BITS - intrinsics.count_leading_zeros(n));
for i := bits_used; i >= 0; i -= 1 {
start := (n >> (uint(i) + 1)) + 1 | 1;
stop := (n >> uint(i)) + 1 | 1;
if err = _int_recursive_product(temp, start, stop); err != .None { return err; }
if err = mul(inner, inner, temp); err != .None { return err; }
if err = mul(outer, outer, inner); err != .None { return err; }
if err = _int_recursive_product(temp, start, stop); err != nil { return err; }
if err = mul(inner, inner, temp); err != nil { return err; }
if err = mul(outer, outer, inner); err != nil { return err; }
}
shift := n - intrinsics.count_ones(n);
@@ -841,7 +841,7 @@ factorial :: proc { int_factorial, };
*/
int_choose_digit :: proc(res: ^Int, n, k: DIGIT) -> (err: Error) {
if res == nil { return .Invalid_Pointer; }
if err = clear_if_uninitialized(res); err != .None { return err; }
if err = clear_if_uninitialized(res); err != nil { return err; }
if k > n { return zero(res); }
@@ -851,12 +851,12 @@ int_choose_digit :: proc(res: ^Int, n, k: DIGIT) -> (err: Error) {
n_fac, k_fac, n_minus_k_fac := &Int{}, &Int{}, &Int{};
defer destroy(n_fac, k_fac, n_minus_k_fac);
if err = factorial(n_minus_k_fac, n - k); err != .None { return err; }
if err = factorial(k_fac, k); err != .None { return err; }
if err = mul(k_fac, k_fac, n_minus_k_fac); err != .None { return err; }
if err = factorial(n_minus_k_fac, n - k); err != nil { return err; }
if err = factorial(k_fac, k); err != nil { return err; }
if err = mul(k_fac, k_fac, n_minus_k_fac); err != nil { return err; }
if err = factorial(n_fac, n); err != .None { return err; }
if err = div(res, n_fac, k_fac); err != .None { return err; }
if err = factorial(n_fac, n); err != nil { return err; }
if err = div(res, n_fac, k_fac); err != nil { return err; }
return err;
}
@@ -886,7 +886,7 @@ _int_add :: proc(dest, a, b: ^Int) -> (err: Error) {
max_used = x.used;
old_used = dest.used;
if err = grow(dest, max(max_used + 1, _DEFAULT_DIGIT_COUNT)); err != .None {
if err = grow(dest, max(max_used + 1, _DEFAULT_DIGIT_COUNT)); err != nil {
return err;
}
dest.used = max_used + 1;
@@ -954,10 +954,10 @@ _int_add :: proc(dest, a, b: ^Int) -> (err: Error) {
*/
_int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
dest := dest; x := number; y := decrease;
if err = clear_if_uninitialized(x); err != .None {
if err = clear_if_uninitialized(x); err != nil {
return err;
}
if err = clear_if_uninitialized(y); err != .None {
if err = clear_if_uninitialized(y); err != nil {
return err;
}
@@ -966,7 +966,7 @@ _int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
max_used := x.used;
i: int;
if err = grow(dest, max(max_used, _DEFAULT_DIGIT_COUNT)); err != .None {
if err = grow(dest, max(max_used, _DEFAULT_DIGIT_COUNT)); err != nil {
return err;
}
dest.used = max_used;
@@ -1042,7 +1042,7 @@ _int_mul :: proc(dest, a, b: ^Int, digits: int) -> (err: Error) {
t := &Int{};
if err = grow(t, max(digits, _DEFAULT_DIGIT_COUNT)); err != .None { return err; }
if err = grow(t, max(digits, _DEFAULT_DIGIT_COUNT)); err != nil { return err; }
t.used = digits;
/*
@@ -1113,7 +1113,7 @@ _int_mul_comba :: proc(dest, a, b: ^Int, digits: int) -> (err: Error) {
/*
Grow the destination as required.
*/
if err = grow(dest, digits); err != .None { return err; }
if err = grow(dest, digits); err != nil { return err; }
/*
Number of output digits to produce.
@@ -1200,7 +1200,7 @@ _int_sqr :: proc(dest, src: ^Int) -> (err: Error) {
/*
Grow `t` to maximum needed size, or `_DEFAULT_DIGIT_COUNT`, whichever is bigger.
*/
if err = grow(t, max((2 * pa) + 1, _DEFAULT_DIGIT_COUNT)); err != .None { return err; }
if err = grow(t, max((2 * pa) + 1, _DEFAULT_DIGIT_COUNT)); err != nil { return err; }
t.used = (2 * pa) + 1;
for ix = 0; ix < pa; ix += 1 {
@@ -1267,7 +1267,7 @@ _int_div_3 :: proc(quotient, numerator: ^Int) -> (remainder: int, err: Error) {
b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3);
q := &Int{};
if err = grow(q, numerator.used); err != .None { return -1, err; }
if err = grow(q, numerator.used); err != nil { return -1, err; }
q.used = numerator.used;
q.sign = numerator.sign;
@@ -1308,7 +1308,7 @@ _int_div_3 :: proc(quotient, numerator: ^Int) -> (remainder: int, err: Error) {
swap(q, quotient);
}
destroy(q);
return remainder, .None;
return remainder, nil;
}
/*
@@ -1320,26 +1320,26 @@ _int_div_small :: proc(quotient, remainder, numerator, denominator: ^Int) -> (er
c: int;
goto_end: for {
if err = one(tq); err != .None { break goto_end; }
if err = one(tq); err != nil { break goto_end; }
num_bits, _ := count_bits(numerator);
den_bits, _ := count_bits(denominator);
n := num_bits - den_bits;
if err = abs(ta, numerator); err != .None { break goto_end; }
if err = abs(tb, denominator); err != .None { break goto_end; }
if err = shl(tb, tb, n); err != .None { break goto_end; }
if err = shl(tq, tq, n); err != .None { break goto_end; }
if err = abs(ta, numerator); err != nil { break goto_end; }
if err = abs(tb, denominator); err != nil { break goto_end; }
if err = shl(tb, tb, n); err != nil { break goto_end; }
if err = shl(tq, tq, n); err != nil { break goto_end; }
for n >= 0 {
if c, _ = cmp_mag(ta, tb); c == 0 || c == 1 {
// ta -= tb
if err = sub(ta, ta, tb); err != .None { break goto_end; }
if err = sub(ta, ta, tb); err != nil { break goto_end; }
// q += tq
if err = add( q, q, tq); err != .None { break goto_end; }
if err = add( q, q, tq); err != nil { break goto_end; }
}
if err = shr1(tb, tb); err != .None { break goto_end; }
if err = shr1(tq, tq); err != .None { break goto_end; }
if err = shr1(tb, tb); err != nil { break goto_end; }
if err = shr1(tq, tq); err != nil { break goto_end; }
n -= 1;
}
@@ -1383,7 +1383,7 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
Quick outs.
*/
if denominator == 1 || numerator.used == 0 {
err = .None;
err = nil;
if quotient != nil {
err = copy(quotient, numerator);
}
@@ -1397,7 +1397,7 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
remainder = 1;
}
if quotient == nil {
return remainder, .None;
return remainder, nil;
}
return remainder, shr(quotient, numerator, 1);
}
@@ -1409,7 +1409,7 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
}
remainder = int(numerator.digit[0]) & ((1 << uint(ix)) - 1);
if quotient == nil {
return remainder, .None;
return remainder, nil;
}
return remainder, shr(quotient, numerator, int(ix));
@@ -1425,7 +1425,7 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
/*
No easy answer [c'est la vie]. Just division.
*/
if err = grow(q, numerator.used); err != .None { return 0, err; }
if err = grow(q, numerator.used); err != nil { return 0, err; }
q.used = numerator.used;
q.sign = numerator.sign;
@@ -1448,42 +1448,42 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
swap(q, quotient);
}
destroy(q);
return remainder, .None;
return remainder, nil;
}
/*
Function computing both GCD and (if target isn't `nil`) also LCM.
*/
int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(res_gcd, res_lcm, a, b); err != .None { return err; }
if err = clear_if_uninitialized(res_gcd, res_lcm, a, b); err != nil { return err; }
az, _ := is_zero(a); bz, _ := is_zero(b);
if az && bz {
if res_gcd != nil {
if err = zero(res_gcd); err != .None { return err; }
if err = zero(res_gcd); err != nil { return err; }
}
if res_lcm != nil {
if err = zero(res_lcm); err != .None { return err; }
if err = zero(res_lcm); err != nil { return err; }
}
return .None;
return nil;
}
else if az {
if res_gcd != nil {
if err = abs(res_gcd, b); err != .None { return err; }
if err = abs(res_gcd, b); err != nil { return err; }
}
if res_lcm != nil {
if err = zero(res_lcm); err != .None { return err; }
if err = zero(res_lcm); err != nil { return err; }
}
return .None;
return nil;
}
else if bz {
if res_gcd != nil {
if err = abs(res_gcd, a); err != .None { return err; }
if err = abs(res_gcd, a); err != nil { return err; }
}
if res_lcm != nil {
if err = zero(res_lcm); err != .None { return err; }
if err = zero(res_lcm); err != nil { return err; }
}
return .None;
return nil;
}
return #force_inline _int_gcd_lcm(res_gcd, res_lcm, a, b);
@@ -1521,7 +1521,7 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
If neither result is wanted, we have nothing to do.
*/
if res_gcd == nil && res_lcm == nil { return .None; }
if res_gcd == nil && res_lcm == nil { return nil; }
/*
We need a temporary because `res_gcd` is allowed to be `nil`.
@@ -1532,34 +1532,34 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
GCD(0, 0) and LCM(0, 0) are both 0.
*/
if res_gcd != nil {
if err = zero(res_gcd); err != .None { return err; }
if err = zero(res_gcd); err != nil { return err; }
}
if res_lcm != nil {
if err = zero(res_lcm); err != .None { return err; }
if err = zero(res_lcm); err != nil { return err; }
}
return .None;
return nil;
} else if az {
/*
We can early out with GCD = B and LCM = 0
*/
if res_gcd != nil {
if err = abs(res_gcd, b); err != .None { return err; }
if err = abs(res_gcd, b); err != nil { return err; }
}
if res_lcm != nil {
if err = zero(res_lcm); err != .None { return err; }
if err = zero(res_lcm); err != nil { return err; }
}
return .None;
return nil;
} else if bz {
/*
We can early out with GCD = A and LCM = 0
*/
if res_gcd != nil {
if err = abs(res_gcd, a); err != .None { return err; }
if err = abs(res_gcd, a); err != nil { return err; }
}
if res_lcm != nil {
if err = zero(res_lcm); err != .None { return err; }
if err = zero(res_lcm); err != nil { return err; }
}
return .None;
return nil;
}
temp_gcd_res := &Int{};
@@ -1571,8 +1571,8 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
*/
u, v := &Int{}, &Int{};
defer destroy(u, v);
if err = copy(u, a); err != .None { return err; }
if err = copy(v, b); err != .None { return err; }
if err = copy(u, a); err != nil { return err; }
if err = copy(v, b); err != nil { return err; }
/*
Must be positive for the remainder of the algorithm.
@@ -1590,18 +1590,18 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
/*
Divide the power of two out.
*/
if err = shr(u, u, k); err != .None { return err; }
if err = shr(v, v, k); err != .None { return err; }
if err = shr(u, u, k); err != nil { return err; }
if err = shr(v, v, k); err != nil { return err; }
}
/*
Divide any remaining factors of two out.
*/
if u_lsb != k {
if err = shr(u, u, u_lsb - k); err != .None { return err; }
if err = shr(u, u, u_lsb - k); err != nil { return err; }
}
if v_lsb != k {
if err = shr(v, v, v_lsb - k); err != .None { return err; }
if err = shr(v, v, v_lsb - k); err != nil { return err; }
}
for v.used != 0 {
@@ -1618,19 +1618,19 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
/*
Subtract smallest from largest.
*/
if err = sub(v, v, u); err != .None { return err; }
if err = sub(v, v, u); err != nil { return err; }
/*
Divide out all factors of two.
*/
b, _ := count_lsb(v);
if err = shr(v, v, b); err != .None { return err; }
if err = shr(v, v, b); err != nil { return err; }
}
/*
Multiply by 2**k which we divided out at the beginning.
*/
if err = shl(temp_gcd_res, u, k); err != .None { return err; }
if err = shl(temp_gcd_res, u, k); err != nil { return err; }
temp_gcd_res.sign = .Zero_or_Positive;
/*
@@ -1639,7 +1639,7 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
*/
if res_lcm == nil {
swap(temp_gcd_res, res_gcd);
return .None;
return nil;
}
/*
@@ -1650,13 +1650,13 @@ _int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int) -> (err: Error) {
/*
Store quotient in `t2` such that `t2 * b` is the LCM.
*/
if err = div(res_lcm, a, temp_gcd_res); err != .None { return err; }
if err = div(res_lcm, a, temp_gcd_res); err != nil { return err; }
err = mul(res_lcm, res_lcm, b);
} else {
/*
Store quotient in `t2` such that `t2 * a` is the LCM.
*/
if err = div(res_lcm, a, temp_gcd_res); err != .None { return err; }
if err = div(res_lcm, a, temp_gcd_res); err != nil { return err; }
err = mul(res_lcm, res_lcm, b);
}

View File

@@ -64,11 +64,18 @@ Int :: struct {
sign: Sign,
};
Flag :: enum u8 {
NaN,
Inf,
Immutable,
};
Flags :: bit_set[Flag; u8];
/*
Errors are a strict superset of runtime.Allocation_Error.
*/
Error :: enum int {
None = 0,
Out_Of_Memory = 1,
Invalid_Pointer = 2,
Invalid_Argument = 3,
@@ -85,7 +92,6 @@ Error :: enum int {
};
Error_String :: #partial [Error]string{
.None = "None",
.Out_Of_Memory = "Out of memory",
.Invalid_Pointer = "Invalid pointer",
.Invalid_Argument = "Invalid argument",

View File

@@ -23,47 +23,47 @@ int_is_initialized :: proc(a: ^Int) -> bool {
}
int_is_zero :: proc(a: ^Int) -> (res: bool, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return false, err;
}
return a.used == 0, .None;
return a.used == 0, nil;
}
int_is_positive :: proc(a: ^Int) -> (res: bool, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return false, err;
}
return a.sign == .Zero_or_Positive, .None;
return a.sign == .Zero_or_Positive, nil;
}
int_is_negative :: proc(a: ^Int) -> (res: bool, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return false, err;
}
return a.sign == .Negative, .None;
return a.sign == .Negative, nil;
}
int_is_even :: proc(a: ^Int) -> (res: bool, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return false, err;
}
res, err = is_zero(a);
if err != .None {
if err != nil {
return false, err;
} else if res == true {
return true, .None;
return true, nil;
}
res = false;
if a.used > 0 && a.digit[0] & 1 == 0 {
res = true;
}
return res, .None;
return res, nil;
}
int_is_odd :: proc(a: ^Int) -> (res: bool, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return false, err;
}
@@ -76,7 +76,7 @@ platform_int_is_power_of_two :: proc(a: int) -> bool {
}
int_is_power_of_two :: proc(a: ^Int) -> (res: bool, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return false, err;
}
@@ -84,21 +84,21 @@ int_is_power_of_two :: proc(a: ^Int) -> (res: bool, err: Error) {
Early out for Int == 0.
*/
if a.used == 0 {
return false, .None;
return false, nil;
}
/*
For an `Int` to be a power of two, its top limb has to be a power of two.
*/
if !platform_int_is_power_of_two(int(a.digit[a.used - 1])) {
return false, .None;
return false, nil;
}
/*
That was the only limb, so it's a power of two.
*/
if a.used == 1 {
return true, .None;
return true, nil;
}
/*
@@ -106,32 +106,32 @@ int_is_power_of_two :: proc(a: ^Int) -> (res: bool, err: Error) {
*/
for i := 1; i < a.used; i += 1 {
if a.digit[i - 1] != 0 {
return false, .None;
return false, nil;
}
}
return true, .None;
return true, nil;
}
/*
Compare two `Int`s, signed.
*/
int_compare :: proc(a, b: ^Int) -> (res: int, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
if err = clear_if_uninitialized(b); err != .None {
if err = clear_if_uninitialized(b); err != nil {
return 0, err;
}
neg: bool;
if neg, err = is_negative(a); err != .None {
if neg, err = is_negative(a); err != nil {
return 0, err;
}
/* Compare based on sign */
if a.sign != b.sign {
res = -1 if neg else +1;
return res, .None;
return res, nil;
}
/* If negative, compare in the opposite direction */
@@ -145,63 +145,63 @@ int_compare :: proc(a, b: ^Int) -> (res: int, err: Error) {
Compare an `Int` to an unsigned number upto the size of the backing type.
*/
int_compare_digit :: proc(a: ^Int, u: DIGIT) -> (res: int, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
/* Compare based on sign */
neg: bool;
if neg, err = is_neg(a); err != .None {
if neg, err = is_neg(a); err != nil {
return 0, err;
}
if neg {
return -1, .None;
return -1, nil;
}
/* Compare based on magnitude */
if a.used > 1 {
return +1, .None;
return +1, nil;
}
/* Compare the only digit in `a` to `u`. */
if a.digit[0] != u {
if a.digit[0] > u {
return +1, .None;
return +1, nil;
}
return -1, .None;
return -1, nil;
}
return 0, .None;
return 0, nil;
}
/*
Compare the magnitude of two `Int`s, unsigned.
*/
int_compare_magnitude :: proc(a, b: ^Int) -> (res: int, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
if err = clear_if_uninitialized(b); err != .None {
if err = clear_if_uninitialized(b); err != nil {
return 0, err;
}
/* Compare based on used digits */
if a.used != b.used {
if a.used > b.used {
return +1, .None;
return +1, nil;
}
return -1, .None;
return -1, nil;
}
/* Same number of used digits, compare based on their value */
for n := a.used - 1; n >= 0; n -= 1 {
if a.digit[n] != b.digit[n] {
if a.digit[n] > b.digit[n] {
return +1, .None;
return +1, nil;
}
return -1, .None;
return -1, nil;
}
}
return 0, .None;
return 0, nil;
}

View File

@@ -102,7 +102,7 @@ print :: proc(name: string, a: ^Int, base := i8(10), print_name := false, newlin
} else {
fmt.printf("%v", as);
}
if err != .None {
if err != nil {
fmt.printf("%v (error: %v | %v)", name, err, a);
}
if newline {
@@ -118,19 +118,22 @@ demo :: proc() {
a, b, c, d, e, f := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
defer destroy(a, b, c, d, e, f);
N :: 5_000;
factorial(a, 128); // Untimed warmup.
N :: 128;
s := time.tick_now();
err = factorial(a, N);
Timings[.factorial].t += time.tick_since(s); Timings[.factorial].c += 1;
if err != .None {
if err != nil {
fmt.printf("factorial(%v) returned %v\n", N, err);
}
s = time.tick_now();
as, err = itoa(a, 16);
Timings[.itoa].t += time.tick_since(s); Timings[.itoa].c += 1;
if err != .None {
if err != nil {
fmt.printf("itoa(factorial(%v), 16) returned %v\n", N, err);
}

View File

@@ -13,7 +13,7 @@ int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
if base < 2 || DIGIT(base) > _DIGIT_MAX {
return -1, .Invalid_Argument;
}
if err = clear_if_uninitialized(a); err != .None { return -1, err; }
if err = clear_if_uninitialized(a); err != nil { return -1, err; }
if n, _ := is_neg(a); n { return -1, .Math_Domain_Error; }
if z, _ := is_zero(a); z { return -1, .Math_Domain_Error; }
@@ -38,8 +38,8 @@ log :: proc { int_log, int_log_digit, };
*/
int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
power := power;
if err = clear_if_uninitialized(base); err != .None { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; }
if err = clear_if_uninitialized(base); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != nil { return err; }
/*
Early outs.
*/
@@ -48,7 +48,7 @@ int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
A zero base is a special case.
*/
if power < 0 {
if err = zero(dest); err != .None { return err; }
if err = zero(dest); err != nil { return err; }
return .Math_Domain_Error;
}
if power == 0 { return one(dest); }
@@ -77,19 +77,19 @@ int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
}
g := &Int{};
if err = copy(g, base); err != .None { return err; }
if err = copy(g, base); err != nil { return err; }
/*
Set initial result.
*/
if err = set(dest, 1); err != .None { return err; }
if err = set(dest, 1); err != nil { return err; }
loop: for power > 0 {
/*
If the bit is set, multiply.
*/
if power & 1 != 0 {
if err = mul(dest, g, dest); err != .None {
if err = mul(dest, g, dest); err != nil {
break loop;
}
}
@@ -97,7 +97,7 @@ int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
Square.
*/
if power > 1 {
if err = sqr(g, g); err != .None {
if err = sqr(g, g); err != nil {
break loop;
}
}
@@ -117,7 +117,7 @@ int_pow_int :: proc(dest: ^Int, base, power: int) -> (err: Error) {
base_t := &Int{};
defer destroy(base_t);
if err = set(base_t, base); err != .None { return err; }
if err = set(base_t, base); err != nil { return err; }
return int_pow(dest, base_t, power);
}
@@ -163,14 +163,14 @@ int_log_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
Therefore, we return 0.
*/
if a < base {
return 0, .None;
return 0, nil;
}
/*
If a number equals the base, the log is 1.
*/
if a == base {
return 1, .None;
return 1, nil;
}
N := _WORD(a);
@@ -199,14 +199,14 @@ int_log_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
bracket_low = bracket_mid;
}
if N == bracket_mid {
return mid, .None;
return mid, nil;
}
}
if bracket_high == N {
return high, .None;
return high, nil;
} else {
return low, .None;
return low, nil;
}
}
@@ -216,8 +216,8 @@ int_log_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
int_sqrt :: proc(dest, src: ^Int) -> (err: Error) {
when true {
if err = clear_if_uninitialized(dest); err != .None { return err; }
if err = clear_if_uninitialized(src); err != .None { return err; }
if err = clear_if_uninitialized(dest); err != nil { return err; }
if err = clear_if_uninitialized(src); err != nil { return err; }
/* Must be positive. */
if src.sign == .Negative { return .Invalid_Argument; }
@@ -230,10 +230,10 @@ int_sqrt :: proc(dest, src: ^Int) -> (err: Error) {
defer destroy(x, y, t1, t2);
count: int;
if count, err = count_bits(src); err != .None { return err; }
if count, err = count_bits(src); err != nil { return err; }
a, b := count >> 1, count & 1;
if err = power_of_two(x, a+b); err != .None { return err; }
if err = power_of_two(x, a+b); err != nil { return err; }
for {
/*
@@ -245,7 +245,7 @@ int_sqrt :: proc(dest, src: ^Int) -> (err: Error) {
if c, _ := cmp(y, x); c == 0 || c == 1 {
swap(dest, x);
return .None;
return nil;
}
swap(x, y);
}
@@ -271,8 +271,8 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
if n == 2 { return sqrt(dest, src); }
/* Initialize dest + src if needed. */
if err = clear_if_uninitialized(dest); err != .None { return err; }
if err = clear_if_uninitialized(src); err != .None { return err; }
if err = clear_if_uninitialized(dest); err != nil { return err; }
if err = clear_if_uninitialized(src); err != nil { return err; }
if n < 0 || n > int(_DIGIT_MAX) {
return .Invalid_Argument;
@@ -280,7 +280,7 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
neg: bool;
if n & 1 == 0 {
if neg, err = is_neg(src); neg || err != .None { return .Invalid_Argument; }
if neg, err = is_neg(src); neg || err != nil { return .Invalid_Argument; }
}
/* Set up temporaries. */
@@ -323,33 +323,33 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
/* Start value must be larger than root. */
ilog2 += 2;
if err = power_of_two(t2, ilog2); err != .None { return err; }
if err = power_of_two(t2, ilog2); err != nil { return err; }
c: int;
iterations := 0;
for {
/* t1 = t2 */
if err = copy(t1, t2); err != .None { return err; }
if err = copy(t1, t2); err != nil { return err; }
/* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
/* t3 = t1**(b-1) */
if err = pow(t3, t1, n-1); err != .None { return err; }
if err = pow(t3, t1, n-1); err != nil { return err; }
/* numerator */
/* t2 = t1**b */
if err = mul(t2, t1, t3); err != .None { return err; }
if err = mul(t2, t1, t3); err != nil { return err; }
/* t2 = t1**b - a */
if err = sub(t2, t2, a); err != .None { return err; }
if err = sub(t2, t2, a); err != nil { return err; }
/* denominator */
/* t3 = t1**(b-1) * b */
if err = mul(t3, t3, DIGIT(n)); err != .None { return err; }
if err = mul(t3, t3, DIGIT(n)); err != nil { return err; }
/* t3 = (t1**b - a)/(b * t1**(b-1)) */
if err = div(t3, t2, t3); err != .None { return err; }
if err = sub(t2, t1, t3); err != .None { return err; }
if err = div(t3, t2, t3); err != nil { return err; }
if err = sub(t2, t1, t3); err != nil { return err; }
/*
Number of rounds is at most log_2(root). If it is more it
@@ -370,14 +370,14 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
iterations = 0;
for {
if err = pow(t2, t1, n); err != .None { return err; }
if err = pow(t2, t1, n); err != nil { return err; }
c, err = cmp(t2, a);
if c == 0 {
swap(dest, t1);
return .None;
return nil;
} else if c == -1 {
if err = add(t1, t1, DIGIT(1)); err != .None { return err; }
if err = add(t1, t1, DIGIT(1)); err != nil { return err; }
} else {
break;
}
@@ -391,11 +391,11 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
iterations = 0;
/* Correct overshoot from above or from recurrence. */
for {
if err = pow(t2, t1, n); err != .None { return err; }
if err = pow(t2, t1, n); err != nil { return err; }
c, err = cmp(t2, a);
if c == 1 {
if err = sub(t1, t1, DIGIT(1)); err != .None { return err; }
if err = sub(t1, t1, DIGIT(1)); err != nil { return err; }
} else {
break;
}
@@ -424,13 +424,13 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
ic, _ := cmp(a, base);
if ic == -1 || ic == 0 {
return 1 if ic == 0 else 0, .None;
return 1 if ic == 0 else 0, nil;
}
if err = set(bi_base, base); err != .None { return -1, err; }
if err = init_multi(bracket_mid, t); err != .None { return -1, err; }
if err = one(bracket_low); err != .None { return -1, err; }
if err = set(bracket_high, base); err != .None { return -1, err; }
if err = set(bi_base, base); err != nil { return -1, err; }
if err = init_multi(bracket_mid, t); err != nil { return -1, err; }
if err = one(bracket_low); err != nil { return -1, err; }
if err = set(bracket_high, base); err != nil { return -1, err; }
low := 0; high := 1;
@@ -450,12 +450,12 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
}
low = high;
if err = copy(bracket_low, bracket_high); err != .None {
if err = copy(bracket_low, bracket_high); err != nil {
destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err;
}
high <<= 1;
if err = sqr(bracket_high, bracket_high); err != .None {
if err = sqr(bracket_high, bracket_high); err != nil {
destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err;
}
@@ -464,12 +464,12 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
for (high - low) > 1 {
mid := (high + low) >> 1;
if err = pow(t, bi_base, mid - low); err != .None {
if err = pow(t, bi_base, mid - low); err != nil {
destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err;
}
if err = mul(bracket_mid, bracket_low, t); err != .None {
if err = mul(bracket_mid, bracket_low, t); err != nil {
destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err;
}
@@ -484,7 +484,7 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
}
if mc == 0 {
destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return mid, .None;
return mid, nil;
}
}

View File

@@ -35,7 +35,7 @@ int_destroy :: proc(integers: ..^Int) {
int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator := context.allocator) -> (err: Error)
where intrinsics.type_is_integer(T) {
src := src;
if err = clear_if_uninitialized(dest); err != .None {
if err = clear_if_uninitialized(dest); err != nil {
return err;
}
dest.used = 0;
@@ -48,7 +48,7 @@ int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator :
src >>= _DIGIT_BITS;
}
_zero_unused(dest);
return .None;
return nil;
}
set :: proc { int_set_from_integer, int_copy };
@@ -57,18 +57,18 @@ set :: proc { int_set_from_integer, int_copy };
Copy one `Int` to another.
*/
int_copy :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
if err = clear_if_uninitialized(src); err != .None { return err; }
if err = clear_if_uninitialized(src); err != nil { return err; }
/*
If dest == src, do nothing
*/
if (dest == src) {
return .None;
return nil;
}
/*
Grow `dest` to fit `src`.
If `dest` is not yet initialized, it will be using `allocator`.
*/
if err = grow(dest, src.used, false, allocator); err != .None {
if err = grow(dest, src.used, false, allocator); err != nil {
return err;
}
@@ -81,7 +81,7 @@ int_copy :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error
dest.used = src.used;
dest.sign = src.sign;
_zero_unused(dest);
return .None;
return nil;
}
copy :: proc { int_copy, };
@@ -106,7 +106,7 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
/*
Check that src is usable.
*/
if err = clear_if_uninitialized(src); err != .None {
if err = clear_if_uninitialized(src); err != nil {
return err;
}
/*
@@ -114,13 +114,13 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
*/
if (dest == src) {
dest.sign = .Zero_or_Positive;
return .None;
return nil;
}
/*
Copy `src` to `dest`
*/
if err = copy(dest, src, allocator); err != .None {
if err = copy(dest, src, allocator); err != nil {
return err;
}
@@ -128,7 +128,7 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
Fix sign.
*/
dest.sign = .Zero_or_Positive;
return .None;
return nil;
}
platform_abs :: proc(n: $T) -> T where intrinsics.type_is_integer(T) {
@@ -143,7 +143,7 @@ neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
/*
Check that src is usable.
*/
if err = clear_if_uninitialized(src); err != .None {
if err = clear_if_uninitialized(src); err != nil {
return err;
}
/*
@@ -158,12 +158,12 @@ neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
}
if (dest == src) {
dest.sign = sign;
return .None;
return nil;
}
/*
Copy `src` to `dest`
*/
if err = copy(dest, src, allocator); err != .None {
if err = copy(dest, src, allocator); err != nil {
return err;
}
@@ -171,7 +171,7 @@ neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
Fix sign.
*/
dest.sign = sign;
return .None;
return nil;
}
/*
@@ -181,7 +181,7 @@ extract_bit :: proc(a: ^Int, bit_offset: int) -> (bit: DIGIT, err: Error) {
/*
Check that `a`is usable.
*/
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
@@ -192,7 +192,7 @@ extract_bit :: proc(a: ^Int, bit_offset: int) -> (bit: DIGIT, err: Error) {
i := DIGIT(1 << DIGIT((bit_offset % _DIGIT_BITS)));
return 1 if ((a.digit[limb] & i) != 0) else 0, .None;
return 1 if ((a.digit[limb] & i) != 0) else 0, nil;
}
/*
@@ -202,7 +202,7 @@ int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: E
/*
Check that `a`is usable.
*/
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
@@ -217,7 +217,7 @@ int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: E
for shift := 0; shift < count; shift += 1 {
o := offset + shift;
v, e = extract_bit(a, o);
if e != .None {
if e != nil {
break;
}
res = res + _WORD(v) << uint(shift);
@@ -258,7 +258,7 @@ int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: E
res |= _WORD(r);
}
return res, .None;
return res, nil;
}
}
@@ -276,7 +276,7 @@ shrink :: proc(a: ^Int) -> (err: Error) {
if a.used != needed {
return grow(a, needed);
}
return .None;
return nil;
}
int_grow :: proc(a: ^Int, digits: int, allow_shrink := false, allocator := context.allocator) -> (err: Error) {
@@ -309,7 +309,7 @@ int_grow :: proc(a: ^Int, digits: int, allow_shrink := false, allocator := conte
if len(a.digit) != needed {
return .Out_Of_Memory;
}
return .None;
return nil;
}
grow :: proc { int_grow, };
@@ -337,12 +337,12 @@ zero :: clear;
Set the `Int` to 1 and optionally shrink it to the minimum backing size.
*/
int_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
if err = clear(a, minimize, allocator); err != .None { return err; }
if err = clear(a, minimize, allocator); err != nil { return err; }
a.used = 1;
a.digit[0] = 1;
a.sign = .Zero_or_Positive;
return .None;
return nil;
}
one :: proc { int_one, };
@@ -350,14 +350,14 @@ one :: proc { int_one, };
Set the `Int` to -1 and optionally shrink it to the minimum backing size.
*/
int_minus_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
if err = clear(a, minimize, allocator); err != .None {
if err = clear(a, minimize, allocator); err != nil {
return err;
}
a.used = 1;
a.digit[0] = 1;
a.sign = .Negative;
return .None;
return nil;
}
minus_one :: proc { int_minus_one, };
@@ -377,7 +377,7 @@ power_of_two :: proc(a: ^Int, power: int) -> (err: Error) {
Grow to accomodate the single bit.
*/
a.used = (power / _DIGIT_BITS) + 1;
if err = grow(a, a.used); err != .None {
if err = grow(a, a.used); err != nil {
return err;
}
/*
@@ -389,7 +389,7 @@ power_of_two :: proc(a: ^Int, power: int) -> (err: Error) {
Set the bit.
*/
a.digit[power / _DIGIT_BITS] = 1 << uint((power % _DIGIT_BITS));
return .None;
return nil;
}
int_get_u128 :: proc(a: ^Int) -> (res: u128, err: Error) {
@@ -427,7 +427,7 @@ get_i32 :: proc { int_get_i32, };
and maybe return max(T), .Integer_Overflow if not?
*/
int_get :: proc(a: ^Int, $T: typeid) -> (res: T, err: Error) where intrinsics.type_is_integer(T) {
if err = clear_if_uninitialized(a); err != .None { return 0, err; }
if err = clear_if_uninitialized(a); err != nil { return 0, err; }
size_in_bits := int(size_of(T) * 8);
i := int((size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS);
@@ -458,7 +458,7 @@ int_get :: proc(a: ^Int, $T: typeid) -> (res: T, err: Error) where intrinsics.ty
get :: proc { int_get, };
int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
@@ -478,14 +478,14 @@ int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) {
Count bits in an `Int`.
*/
count_bits :: proc(a: ^Int) -> (count: int, err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
/*
Fast path for zero.
*/
if z, _ := is_zero(a); z {
return 0, .None;
return 0, nil;
}
/*
Get the number of DIGITs and use it.
@@ -504,13 +504,13 @@ count_bits :: proc(a: ^Int) -> (count: int, err: Error) {
Differs from regular `ctz` in that 0 returns 0.
*/
int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {
if err = clear_if_uninitialized(a); err != .None { return -1, err; }
if err = clear_if_uninitialized(a); err != nil { return -1, err; }
_ctz :: intrinsics.count_trailing_zeros;
/*
Easy out.
*/
if z, _ := is_zero(a); z { return 0, .None; }
if z, _ := is_zero(a); z { return 0, nil; }
/*
Scan lower digits until non-zero.
@@ -520,7 +520,7 @@ int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {
q := a.digit[x];
x *= _DIGIT_BITS;
return x + count_lsb(q), .None;
return x + count_lsb(q), nil;
}
platform_count_lsb :: #force_inline proc(a: $T) -> (count: int)
@@ -554,7 +554,7 @@ int_rand :: proc(dest: ^Int, bits: int, r: ^rnd.Rand = nil) -> (err: Error) {
digits += 1;
}
if err = grow(dest, digits); err != .None { return err; }
if err = grow(dest, digits); err != nil { return err; }
for i := 0; i < digits; i += 1 {
dest.digit[i] = int_random_digit(r) & _MASK;
@@ -563,7 +563,7 @@ int_rand :: proc(dest: ^Int, bits: int, r: ^rnd.Rand = nil) -> (err: Error) {
dest.digit[digits - 1] &= ((1 << uint(bits)) - 1);
}
dest.used = digits;
return .None;
return nil;
}
rand :: proc { int_rand, };
@@ -597,7 +597,7 @@ clear_if_uninitialized_multi :: proc(args: ..^Int) -> (err: Error) {
for i in args {
if i != nil && !is_initialized(i) {
e := grow(i, _DEFAULT_DIGIT_COUNT);
if e != .None { err = e; }
if e != nil { err = e; }
}
}
return err;
@@ -611,27 +611,27 @@ clear_if_uninitialized :: proc {clear_if_uninitialized_single, clear_if_uninitia
int_init_multi :: proc(integers: ..^Int) -> (err: Error) {
integers := integers;
for a in &integers {
if err = clear(a); err != .None { return err; }
if err = clear(a); err != nil { return err; }
}
return .None;
return nil;
}
init_multi :: proc { int_init_multi, };
_copy_digits :: proc(dest, src: ^Int, digits: int) -> (err: Error) {
digits := digits;
if err = clear_if_uninitialized(src); err != .None { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; }
if err = clear_if_uninitialized(src); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != nil { return err; }
/*
If dest == src, do nothing
*/
if (dest == src) {
return .None;
return nil;
}
digits = min(digits, len(src.digit), len(dest.digit));
mem.copy_non_overlapping(&dest.digit[0], &src.digit[0], size_of(DIGIT) * digits);
return .None;
return nil;
}
/*
@@ -641,7 +641,7 @@ _copy_digits :: proc(dest, src: ^Int, digits: int) -> (err: Error) {
Typically very fast. Also fixes the sign if there are no more leading digits.
*/
clamp :: proc(a: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return err;
}
for a.used > 0 && a.digit[a.used - 1] == 0 {
@@ -651,7 +651,7 @@ clamp :: proc(a: ^Int) -> (err: Error) {
if z, _ := is_zero(a); z {
a.sign = .Zero_or_Positive;
}
return .None;
return nil;
}

View File

@@ -24,13 +24,13 @@ import "core:mem"
2's complement `and`, returns `dest = a & b;`
*/
int_and :: proc(dest, a, b: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(a, b); err != .None { return err; }
if err = clear_if_uninitialized(a, b); err != nil { return err; }
used := max(a.used, b.used) + 1;
/*
Grow the destination to accomodate the result.
*/
if err = grow(dest, used); err != .None { return err; }
if err = grow(dest, used); err != nil { return err; }
neg_a, _ := is_neg(a);
neg_b, _ := is_neg(b);
@@ -85,12 +85,12 @@ and :: proc { int_add, };
2's complement `or`, returns `dest = a | b;`
*/
int_or :: proc(dest, a, b: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(a, b); err != .None { return err; }
if err = clear_if_uninitialized(a, b); err != nil { return err; }
used := max(a.used, b.used) + 1;
/*
Grow the destination to accomodate the result.
*/
if err = grow(dest, used); err != .None { return err; }
if err = grow(dest, used); err != nil { return err; }
neg_a, _ := is_neg(a);
neg_b, _ := is_neg(b);
@@ -145,13 +145,13 @@ or :: proc { int_or, };
2's complement `xor`, returns `dest = a ~ b;`
*/
int_xor :: proc(dest, a, b: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(a, b); err != .None { return err; }
if err = clear_if_uninitialized(a, b); err != nil { return err; }
used := max(a.used, b.used) + 1;
/*
Grow the destination to accomodate the result.
*/
if err = grow(dest, used); err != .None { return err; }
if err = grow(dest, used); err != nil { return err; }
neg_a, _ := is_neg(a);
neg_b, _ := is_neg(b);
@@ -209,7 +209,7 @@ int_complement :: proc(dest, src: ^Int) -> (err: Error) {
/*
Check that src is usable. Dest will get checked by `sub`.
*/
if err = clear_if_uninitialized(src); err != .None { return err; }
if err = clear_if_uninitialized(src); err != nil { return err; }
/*
Temporarily fix sign.
@@ -235,25 +235,25 @@ complement :: proc { int_complement, };
*/
int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int) -> (err: Error) {
bits := bits;
if err = clear_if_uninitialized(quotient, numerator); err != .None { return err; }
if err = clear_if_uninitialized(quotient, numerator); err != nil { return err; }
if bits < 0 { return .Invalid_Argument; }
if err = copy(quotient, numerator); err != .None { return err; }
if err = copy(quotient, numerator); err != nil { return err; }
/*
Shift right by a certain bit count (store quotient and optional remainder.)
`numerator` should not be used after this.
*/
if remainder != nil {
if err = mod_bits(remainder, numerator, bits); err != .None { return err; }
if err = mod_bits(remainder, numerator, bits); err != nil { return err; }
}
/*
Shift by as many digits in the bit count.
*/
if bits >= _DIGIT_BITS {
if err = shr_digit(quotient, bits / _DIGIT_BITS); err != .None { return err; }
if err = shr_digit(quotient, bits / _DIGIT_BITS); err != nil { return err; }
}
/*
@@ -299,9 +299,9 @@ int_shr_digit :: proc(quotient: ^Int, digits: int) -> (err: Error) {
/*
Check that `quotient` is usable.
*/
if err = clear_if_uninitialized(quotient); err != .None { return err; }
if err = clear_if_uninitialized(quotient); err != nil { return err; }
if digits <= 0 { return .None; }
if digits <= 0 { return nil; }
/*
If digits > used simply zero and return.
@@ -332,15 +332,15 @@ shr_digit :: proc { int_shr_digit, };
Shift right by a certain bit count with sign extension.
*/
int_shr_signed :: proc(dest, src: ^Int, bits: int) -> (err: Error) {
if err = clear_if_uninitialized(src); err != .None { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; }
if err = clear_if_uninitialized(src); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != nil { return err; }
if src.sign == .Zero_or_Positive {
return shr(dest, src, bits);
}
if err = add(dest, src, DIGIT(1)); err != .None { return err; }
if err = add(dest, src, DIGIT(1)); err != nil { return err; }
if err = shr(dest, dest, bits); err != .None { return err; }
if err = shr(dest, dest, bits); err != nil { return err; }
return sub(dest, src, DIGIT(1));
}
@@ -351,25 +351,25 @@ shr_signed :: proc { int_shr_signed, };
*/
int_shl :: proc(dest, src: ^Int, bits: int) -> (err: Error) {
bits := bits;
if err = clear_if_uninitialized(src, dest); err != .None { return err; }
if err = clear_if_uninitialized(src, dest); err != nil { return err; }
if bits < 0 {
return .Invalid_Argument;
}
if err = copy(dest, src); err != .None { return err; }
if err = copy(dest, src); err != nil { return err; }
/*
Grow `dest` to accommodate the additional bits.
*/
digits_needed := dest.used + (bits / _DIGIT_BITS) + 1;
if err = grow(dest, digits_needed); err != .None { return err; }
if err = grow(dest, digits_needed); err != nil { return err; }
dest.used = digits_needed;
/*
Shift by as many digits in the bit count as we have.
*/
if bits >= _DIGIT_BITS {
if err = shl_digit(dest, bits / _DIGIT_BITS); err != .None { return err; }
if err = shl_digit(dest, bits / _DIGIT_BITS); err != nil { return err; }
}
/*
@@ -407,20 +407,20 @@ int_shl_digit :: proc(quotient: ^Int, digits: int) -> (err: Error) {
/*
Check that `quotient` is usable.
*/
if err = clear_if_uninitialized(quotient); err != .None { return err; }
if err = clear_if_uninitialized(quotient); err != nil { return err; }
if digits <= 0 { return .None; }
if digits <= 0 { return nil; }
/*
No need to shift a zero.
*/
z: bool;
if z, err = is_zero(quotient); z || err != .None { return err; }
if z, err = is_zero(quotient); z || err != nil { return err; }
/*
Resize `quotient` to accomodate extra digits.
*/
if err = grow(quotient, quotient.used + digits); err != .None { return err; }
if err = grow(quotient, quotient.used + digits); err != nil { return err; }
/*
Increment the used by the shift amount then copy upwards.
@@ -436,6 +436,6 @@ int_shl_digit :: proc(quotient: ^Int, digits: int) -> (err: Error) {
quotient.used += digits;
mem.zero_slice(quotient.digit[:digits]);
return .None;
return nil;
}
shl_digit :: proc { int_shl_digit, };

View File

@@ -19,7 +19,7 @@ import "core:mem"
*/
int_itoa_string :: proc(a: ^Int, radix := i8(-1), zero_terminate := false, allocator := context.allocator) -> (res: string, err: Error) {
a := a; radix := radix;
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return "", err;
}
/*
@@ -39,7 +39,7 @@ int_itoa_string :: proc(a: ^Int, radix := i8(-1), zero_terminate := false, alloc
/*
Exit if calculating the size returned an error.
*/
if size, err = radix_size(a, radix, zero_terminate); err != .None {
if size, err = radix_size(a, radix, zero_terminate); err != nil {
return "", err;
}
@@ -62,7 +62,7 @@ int_itoa_string :: proc(a: ^Int, radix := i8(-1), zero_terminate := false, alloc
*/
int_itoa_cstring :: proc(a: ^Int, radix := i8(-1), allocator := context.allocator) -> (res: cstring, err: Error) {
a := a; radix := radix;
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return "", err;
}
/*
@@ -97,7 +97,7 @@ int_itoa_cstring :: proc(a: ^Int, radix := i8(-1), allocator := context.allocato
*/
int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_terminate := false) -> (written: int, err: Error) {
a := a; radix := radix; size := size;
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
/*
@@ -112,7 +112,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
We weren't given a size. Let's compute it.
*/
if size == -1 {
if size, err = radix_size(a, radix, zero_terminate); err != .None {
if size, err = radix_size(a, radix, zero_terminate); err != nil {
return 0, err;
}
}
@@ -149,7 +149,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
diff := size - written;
mem.copy(&buffer[0], &buffer[diff], written);
}
return written, .None;
return written, nil;
}
/*
@@ -182,7 +182,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
diff := size - written;
mem.copy(&buffer[0], &buffer[diff], written);
}
return written, .None;
return written, nil;
}
/*
@@ -202,7 +202,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
for offset := 0; offset < count; offset += shift {
bits_to_get := int(min(count - offset, shift));
if digit, err = int_bitfield_extract(a, offset, bits_to_get); err != .None {
if digit, err = int_bitfield_extract(a, offset, bits_to_get); err != nil {
return len(buffer) - available, .Invalid_Argument;
}
available -= 1;
@@ -222,7 +222,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
diff := size - written;
mem.copy(&buffer[0], &buffer[diff], written);
}
return written, .None;
return written, nil;
}
return _itoa_raw_full(a, radix, buffer, zero_terminate);
@@ -248,13 +248,13 @@ int_atoi :: proc(res: ^Int, input: string, radix: i8) -> (err: Error) {
/*
Set the integer to the default of zero.
*/
if err = zero(res); err != .None { return err; }
if err = zero(res); err != nil { return err; }
/*
We'll interpret an empty string as zero.
*/
if len(input) == 0 {
return .None;
return nil;
}
/*
@@ -295,8 +295,8 @@ int_atoi :: proc(res: ^Int, input: string, radix: i8) -> (err: Error) {
break;
}
if err = mul(res, res, DIGIT(radix)); err != .None { return err; }
if err = add(res, res, DIGIT(y)); err != .None { return err; }
if err = mul(res, res, DIGIT(radix)); err != nil { return err; }
if err = add(res, res, DIGIT(y)); err != nil { return err; }
input = input[1:];
}
@@ -313,7 +313,7 @@ int_atoi :: proc(res: ^Int, input: string, radix: i8) -> (err: Error) {
res.sign = sign;
}
return .None;
return nil;
}
@@ -327,15 +327,15 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false) -> (size: int, e
if radix < 2 || radix > 64 {
return -1, .Invalid_Argument;
}
if err = clear_if_uninitialized(a); err != .None {
if err = clear_if_uninitialized(a); err != nil {
return 0, err;
}
if z, _ := is_zero(a); z {
if zero_terminate {
return 2, .None;
return 2, nil;
}
return 1, .None;
return 1, nil;
}
if pot, _ := is_power_of_two(a); pot {
@@ -348,7 +348,7 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false) -> (size: int, e
digit = a.digit,
};
if size, err = log(t, DIGIT(radix)); err != .None {
if size, err = log(t, DIGIT(radix)); err != nil {
return 0, err;
}
} else {
@@ -364,8 +364,8 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false) -> (size: int, e
err = set(k, lb[radix]);
/* n = floor((la * k) / 2^29) + 1 */
if err = mul(k, la, k); err != .None { return 0, err; }
if err = shr(k, k, _RADIX_SIZE_SCALE); err != .None { return 0, err; }
if err = mul(k, la, k); err != nil { return 0, err; }
if err = shr(k, k, _RADIX_SIZE_SCALE); err != nil { return 0, err; }
/* The "+1" here is the "+1" in "floor((la * k) / 2^29) + 1" */
/* n = n + 1 + EOS + sign */
@@ -378,7 +378,7 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false) -> (size: int, e
*/
size += 2 if a.sign == .Negative else 1;
size += 1 if zero_terminate else 0;
return size, .None;
return size, nil;
}
/*
@@ -435,8 +435,8 @@ RADIX_TABLE_REVERSE_SIZE :: 80;
_itoa_raw_full :: proc(a: ^Int, radix: i8, buffer: []u8, zero_terminate := false) -> (written: int, err: Error) {
temp, denominator := &Int{}, &Int{};
if err = copy(temp, a); err != .None { return 0, err; }
if err = set(denominator, radix); err != .None { return 0, err; }
if err = copy(temp, a); err != nil { return 0, err; }
if err = set(denominator, radix); err != nil { return 0, err; }
available := len(buffer);
if zero_terminate {
@@ -450,7 +450,7 @@ _itoa_raw_full :: proc(a: ^Int, radix: i8, buffer: []u8, zero_terminate := false
remainder: int;
for {
if remainder, err = _int_div_digit(temp, temp, DIGIT(radix)); err != .None {
if remainder, err = _int_div_digit(temp, temp, DIGIT(radix)); err != nil {
destroy(temp, denominator);
return len(buffer) - available, err;
}
@@ -476,5 +476,5 @@ _itoa_raw_full :: proc(a: ^Int, radix: i8, buffer: []u8, zero_terminate := false
diff := len(buffer) - written;
mem.copy(&buffer[0], &buffer[diff], written);
}
return written, .None;
return written, nil;
}

View File

@@ -33,14 +33,14 @@ PyRes :: struct {
aa, bb, sum := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, sum);
if err = atoi(aa, string(a), 16); err != .None { return PyRes{res=":add:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != .None { return PyRes{res=":add:atoi(b):", err=err}; }
if err = add(sum, aa, bb); err != .None { return PyRes{res=":add:add(sum,a,b):", err=err}; }
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":add:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":add:atoi(b):", err=err}; }
if err = add(sum, aa, bb); err != nil { return PyRes{res=":add:add(sum,a,b):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(sum, 16, context.temp_allocator);
if err != .None { return PyRes{res=":add:itoa(sum):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":add:itoa(sum):", err=err}; }
return PyRes{res = r, err = nil};
}
@export test_sub :: proc "c" (a, b: cstring) -> (res: PyRes) {
@@ -50,14 +50,14 @@ PyRes :: struct {
aa, bb, sum := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, sum);
if err = atoi(aa, string(a), 16); err != .None { return PyRes{res=":sub:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != .None { return PyRes{res=":sub:atoi(b):", err=err}; }
if err = sub(sum, aa, bb); err != .None { return PyRes{res=":sub:sub(sum,a,b):", err=err}; }
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":sub:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":sub:atoi(b):", err=err}; }
if err = sub(sum, aa, bb); err != nil { return PyRes{res=":sub:sub(sum,a,b):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(sum, 16, context.temp_allocator);
if err != .None { return PyRes{res=":sub:itoa(sum):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":sub:itoa(sum):", err=err}; }
return PyRes{res = r, err = nil};
}
@export test_mul :: proc "c" (a, b: cstring) -> (res: PyRes) {
@@ -67,14 +67,14 @@ PyRes :: struct {
aa, bb, product := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, product);
if err = atoi(aa, string(a), 16); err != .None { return PyRes{res=":mul:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != .None { return PyRes{res=":mul:atoi(b):", err=err}; }
if err = mul(product, aa, bb); err != .None { return PyRes{res=":mul:mul(product,a,b):", err=err}; }
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":mul:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":mul:atoi(b):", err=err}; }
if err = mul(product, aa, bb); err != nil { return PyRes{res=":mul:mul(product,a,b):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(product, 16, context.temp_allocator);
if err != .None { return PyRes{res=":mul:itoa(product):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":mul:itoa(product):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -87,14 +87,14 @@ PyRes :: struct {
aa, bb, quotient := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, quotient);
if err = atoi(aa, string(a), 16); err != .None { return PyRes{res=":div:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != .None { return PyRes{res=":div:atoi(b):", err=err}; }
if err = div(quotient, aa, bb); err != .None { return PyRes{res=":div:div(quotient,a,b):", err=err}; }
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":div:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":div:atoi(b):", err=err}; }
if err = div(quotient, aa, bb); err != nil { return PyRes{res=":div:div(quotient,a,b):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(quotient, 16, context.temp_allocator);
if err != .None { return PyRes{res=":div:itoa(quotient):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":div:itoa(quotient):", err=err}; }
return PyRes{res = r, err = nil};
}
@@ -109,8 +109,8 @@ PyRes :: struct {
aa := &Int{};
defer destroy(aa);
if err = atoi(aa, string(a), 16); err != .None { return PyRes{res=":log:atoi(a):", err=err}; }
if l, err = log(aa, base); err != .None { return PyRes{res=":log:log(a, base):", err=err}; }
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":log:atoi(a):", err=err}; }
if l, err = log(aa, base); err != nil { return PyRes{res=":log:log(a, base):", err=err}; }
zero(aa);
aa.digit[0] = DIGIT(l) & _MASK;
@@ -120,8 +120,8 @@ PyRes :: struct {
r: cstring;
r, err = int_itoa_cstring(aa, 16, context.temp_allocator);
if err != .None { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -134,13 +134,13 @@ PyRes :: struct {
dest, bb := &Int{}, &Int{};
defer destroy(dest, bb);
if err = atoi(bb, string(base), 16); err != .None { return PyRes{res=":pow:atoi(base):", err=err}; }
if err = pow(dest, bb, power); err != .None { return PyRes{res=":pow:pow(dest, base, power):", err=err}; }
if err = atoi(bb, string(base), 16); err != nil { return PyRes{res=":pow:atoi(base):", err=err}; }
if err = pow(dest, bb, power); err != nil { return PyRes{res=":pow:pow(dest, base, power):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -153,13 +153,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":sqrt:atoi(src):", err=err}; }
if err = sqrt(src, src); err != .None { return PyRes{res=":sqrt:sqrt(src):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":sqrt:atoi(src):", err=err}; }
if err = sqrt(src, src); err != nil { return PyRes{res=":sqrt:sqrt(src):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -172,13 +172,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":root_n:atoi(src):", err=err}; }
if err = root_n(src, src, power); err != .None { return PyRes{res=":root_n:root_n(src):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":root_n:atoi(src):", err=err}; }
if err = root_n(src, src, power); err != nil { return PyRes{res=":root_n:root_n(src):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":root_n:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":root_n:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -191,13 +191,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shr_digit:atoi(src):", err=err}; }
if err = shr_digit(src, digits); err != .None { return PyRes{res=":shr_digit:shr_digit(src):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_digit:atoi(src):", err=err}; }
if err = shr_digit(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shr_digit:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":shr_digit:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -210,13 +210,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shl_digit:atoi(src):", err=err}; }
if err = shl_digit(src, digits); err != .None { return PyRes{res=":shl_digit:shr_digit(src):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shl_digit:atoi(src):", err=err}; }
if err = shl_digit(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shl_digit:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":shl_digit:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -229,13 +229,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shr:atoi(src):", err=err}; }
if err = shr(src, src, bits); err != .None { return PyRes{res=":shr:shr(src, bits):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shr:atoi(src):", err=err}; }
if err = shr(src, src, bits); err != nil { return PyRes{res=":shr:shr(src, bits):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shr:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":shr:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -248,13 +248,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shr_signed:atoi(src):", err=err}; }
if err = shr_signed(src, src, bits); err != .None { return PyRes{res=":shr_signed:shr_signed(src, bits):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_signed:atoi(src):", err=err}; }
if err = shr_signed(src, src, bits); err != nil { return PyRes{res=":shr_signed:shr_signed(src, bits):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shr_signed:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":shr_signed:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -267,13 +267,13 @@ PyRes :: struct {
src := &Int{};
defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shl:atoi(src):", err=err}; }
if err = shl(src, src, bits); err != .None { return PyRes{res=":shl:shl(src, bits):", err=err}; }
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shl:atoi(src):", err=err}; }
if err = shl(src, src, bits); err != nil { return PyRes{res=":shl:shl(src, bits):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shl:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":shl:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -286,12 +286,12 @@ PyRes :: struct {
dest := &Int{};
defer destroy(dest);
if err = factorial(dest, n); err != .None { return PyRes{res=":factorial:factorial(n):", err=err}; }
if err = factorial(dest, n); err != nil { return PyRes{res=":factorial:factorial(n):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":factorial:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":factorial:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -304,14 +304,14 @@ PyRes :: struct {
ai, bi, dest := &Int{}, &Int{}, &Int{};
defer destroy(ai, bi, dest);
if err = atoi(ai, string(a), 16); err != .None { return PyRes{res=":gcd:atoi(a):", err=err}; }
if err = atoi(bi, string(b), 16); err != .None { return PyRes{res=":gcd:atoi(b):", err=err}; }
if err = gcd(dest, ai, bi); err != .None { return PyRes{res=":gcd:gcd(a, b):", err=err}; }
if err = atoi(ai, string(a), 16); err != nil { return PyRes{res=":gcd:atoi(a):", err=err}; }
if err = atoi(bi, string(b), 16); err != nil { return PyRes{res=":gcd:atoi(b):", err=err}; }
if err = gcd(dest, ai, bi); err != nil { return PyRes{res=":gcd:gcd(a, b):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":gcd:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":gcd:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}
/*
@@ -324,13 +324,13 @@ PyRes :: struct {
ai, bi, dest := &Int{}, &Int{}, &Int{};
defer destroy(ai, bi, dest);
if err = atoi(ai, string(a), 16); err != .None { return PyRes{res=":lcm:atoi(a):", err=err}; }
if err = atoi(bi, string(b), 16); err != .None { return PyRes{res=":lcm:atoi(b):", err=err}; }
if err = lcm(dest, ai, bi); err != .None { return PyRes{res=":lcm:lcm(a, b):", err=err}; }
if err = atoi(ai, string(a), 16); err != nil { return PyRes{res=":lcm:atoi(a):", err=err}; }
if err = atoi(bi, string(b), 16); err != nil { return PyRes{res=":lcm:atoi(b):", err=err}; }
if err = lcm(dest, ai, bi); err != nil { return PyRes{res=":lcm:lcm(a, b):", err=err}; }
r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":lcm:itoa(res):", err=err}; }
return PyRes{res = r, err = .None};
if err != nil { return PyRes{res=":lcm:itoa(res):", err=err}; }
return PyRes{res = r, err = nil};
}