big: Error.None -> nil

This commit is contained in:
Jeroen van Rijn
2021-08-11 20:59:52 +02:00
parent 627872db97
commit 97d80d03f9
9 changed files with 368 additions and 359 deletions
+108 -108
View File
@@ -25,9 +25,9 @@ import "core:intrinsics"
*/ */
int_add :: proc(dest, a, b: ^Int) -> (err: Error) { int_add :: proc(dest, a, b: ^Int) -> (err: Error) {
dest := dest; x := a; y := b; dest := dest; x := a; y := b;
if err = clear_if_uninitialized(x); err != .None { return err; } if err = clear_if_uninitialized(x); err != nil { return err; }
if err = clear_if_uninitialized(y); err != .None { return err; } if err = clear_if_uninitialized(y); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; } if err = clear_if_uninitialized(dest); err != nil { return err; }
/* /*
All parameters have been initialized. All parameters have been initialized.
We can now safely ignore errors from comparison routines. 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) { int_add_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
dest := dest; digit := digit; dest := dest; digit := digit;
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return err; return err;
} }
/* /*
Grow destination as required. Grow destination as required.
*/ */
if err = grow(dest, a.used + 1); err != .None { if err = grow(dest, a.used + 1); err != nil {
return err; return err;
} }
@@ -110,7 +110,7 @@ int_add_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
/* /*
dest = |a| - digit dest = |a| - digit
*/ */
if err = sub(dest, a, digit); err != .None { if err = sub(dest, a, digit); err != nil {
/* /*
Restore a's sign. 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) { int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
dest := dest; x := number; y := decrease; dest := dest; x := number; y := decrease;
if err = clear_if_uninitialized(dest); err != .None { if err = clear_if_uninitialized(dest); err != nil {
return err; return err;
} }
if err = clear_if_uninitialized(x); err != .None { if err = clear_if_uninitialized(x); err != nil {
return err; return err;
} }
if err = clear_if_uninitialized(y); err != .None { if err = clear_if_uninitialized(y); err != nil {
return err; 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) { int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error) {
dest := dest; digit := digit; dest := dest; digit := digit;
if err = clear_if_uninitialized(dest); err != .None { if err = clear_if_uninitialized(dest); err != nil {
return err; return err;
} }
/* /*
Grow destination as required. Grow destination as required.
*/ */
if dest != a { if dest != a {
if err = grow(dest, a.used + 1); err != .None { if err = grow(dest, a.used + 1); err != nil {
return err; 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) { if n, _ := is_neg(dest); n && (dest.digit[0] + digit < _DIGIT_MAX) {
dest.digit[0] += digit; dest.digit[0] += digit;
return .None; return nil;
} }
/* /*
Can be subtracted from dest.digit[0] without underflow. Can be subtracted from dest.digit[0] without underflow.
*/ */
if p, _ := is_pos(a); p && (dest.digit[0] > digit) { if p, _ := is_pos(a); p && (dest.digit[0] > digit) {
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) { int_halve :: proc(dest, src: ^Int) -> (err: Error) {
dest := dest; src := src; dest := dest; src := src;
if err = clear_if_uninitialized(dest); err != .None { if err = clear_if_uninitialized(dest); err != nil {
return err; return err;
} }
/* /*
Grow destination as required. Grow destination as required.
*/ */
if dest != src { if dest != src {
if err = grow(dest, src.used); err != .None { if err = grow(dest, src.used); err != nil {
return err; return err;
} }
} }
@@ -397,14 +397,14 @@ shr1 :: halve;
*/ */
int_double :: proc(dest, src: ^Int) -> (err: Error) { int_double :: proc(dest, src: ^Int) -> (err: Error) {
dest := dest; src := src; dest := dest; src := src;
if err = clear_if_uninitialized(dest); err != .None { if err = clear_if_uninitialized(dest); err != nil {
return err; return err;
} }
/* /*
Grow destination as required. Grow destination as required.
*/ */
if dest != src { if dest != src {
if err = grow(dest, src.used + 1); err != .None { if err = grow(dest, src.used + 1); err != nil {
return err; return err;
} }
} }
@@ -462,8 +462,8 @@ shl1 :: double;
remainder = numerator % (1 << bits) remainder = numerator % (1 << bits)
*/ */
int_mod_bits :: proc(remainder, numerator: ^Int, bits: int) -> (err: Error) { 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(remainder); err != nil { return err; }
if err = clear_if_uninitialized(numerator); err != .None { return err; } if err = clear_if_uninitialized(numerator); err != nil { return err; }
if bits < 0 { return .Invalid_Argument; } if bits < 0 { return .Invalid_Argument; }
if bits == 0 { return zero(remainder); } 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. If the modulus is larger than the value, return the value.
*/ */
err = copy(remainder, numerator); err = copy(remainder, numerator);
if bits >= (numerator.used * _DIGIT_BITS) || err != .None { if bits >= (numerator.used * _DIGIT_BITS) || err != nil {
return; return;
} }
@@ -499,7 +499,7 @@ mod_bits :: proc { int_mod_bits, };
Multiply by a DIGIT. Multiply by a DIGIT.
*/ */
int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT) -> (err: Error) { 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 { if multiplier == 0 {
return zero(dest); 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)) { if is_power_of_two(int(multiplier)) {
ix: int; 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); return shl(dest, src, ix);
} }
/* /*
Ensure `dest` is big enough to hold `src` * `multiplier`. 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. 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). High level multiplication (handles sign).
*/ */
int_mul :: proc(dest, src, multiplier: ^Int) -> (err: Error) { 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. 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. 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(numerator); err != nil { return err; }
if err = clear_if_uninitialized(denominator); err != .None { return err; } if err = clear_if_uninitialized(denominator); err != nil { return err; }
z: bool; z: bool;
if z, err = is_zero(denominator); z { return .Division_by_Zero; } 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; c: int;
if c, err = cmp_mag(numerator, denominator); c == -1 { if c, err = cmp_mag(numerator, denominator); c == -1 {
if remainder != nil { if remainder != nil {
if err = copy(remainder, numerator); err != .None { return err; } if err = copy(remainder, numerator); err != nil { return err; }
} }
if quotient != nil { if quotient != nil {
zero(quotient); zero(quotient);
} }
return .None; return nil;
} }
if false && (denominator.used > 2 * _MUL_KARATSUBA_CUTOFF) && (denominator.used <= (numerator.used/3) * 2) { 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 denominator < remainder <= 0 if denominator < 0
*/ */
int_mod :: proc(remainder, numerator, denominator: ^Int) -> (err: Error) { 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; 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); return add(remainder, remainder, numerator);
} }
mod :: proc { int_mod, }; mod :: proc { int_mod, };
@@ -714,7 +714,7 @@ mod :: proc { int_mod, };
remainder = (number + addend) % modulus. remainder = (number + addend) % modulus.
*/ */
int_addmod :: proc(remainder, number, addend, modulus: ^Int) -> (err: Error) { 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); return mod(remainder, remainder, modulus);
} }
addmod :: proc { int_addmod, }; addmod :: proc { int_addmod, };
@@ -723,7 +723,7 @@ addmod :: proc { int_addmod, };
remainder = (number - decrease) % modulus. remainder = (number - decrease) % modulus.
*/ */
int_submod :: proc(remainder, number, decrease, modulus: ^Int) -> (err: Error) { 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); return mod(remainder, remainder, modulus);
} }
submod :: proc { int_submod, }; submod :: proc { int_submod, };
@@ -732,7 +732,7 @@ submod :: proc { int_submod, };
remainder = (number * multiplicand) % modulus. remainder = (number * multiplicand) % modulus.
*/ */
int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int) -> (err: Error) { 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); return mod(remainder, remainder, modulus);
} }
mulmod :: proc { int_mulmod, }; mulmod :: proc { int_mulmod, };
@@ -741,7 +741,7 @@ mulmod :: proc { int_mulmod, };
remainder = (number * number) % modulus. remainder = (number * number) % modulus.
*/ */
int_sqrmod :: proc(remainder, number, modulus: ^Int) -> (err: Error) { 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); return mod(remainder, remainder, modulus);
} }
sqrmod :: proc { int_sqrmod, }; sqrmod :: proc { int_sqrmod, };
@@ -762,13 +762,13 @@ int_factorial :: proc(res: ^Int, n: DIGIT) -> (err: Error) {
return int_factorial_binary_split(res, n); 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 { 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; i += 1;
} }
return .None; return nil;
} }
_int_recursive_product :: proc(res: ^Int, start, stop: DIGIT, level := int(0)) -> (err: Error) { _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; num_factors := (stop - start) >> 1;
if num_factors == 2 { if num_factors == 2 {
if err = set(t1, start); err != .None { return err; } if err = set(t1, start); err != nil { return err; }
if err = add(t2, t1, 2); err != .None { return err; } if err = add(t2, t1, 2); err != nil { return err; }
return mul(res, t1, t2); return mul(res, t1, t2);
} }
if num_factors > 1 { if num_factors > 1 {
mid := (start + 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(t1, start, mid, level + 1); err != nil { return err; }
if err = _int_recursive_product(t2, mid, stop, level + 1); err != .None { return err; } if err = _int_recursive_product(t2, mid, stop, level + 1); err != nil { return err; }
return mul(res, t1, t2); 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{}; inner, outer, start, stop, temp := &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
defer destroy(inner, outer, start, stop, temp); defer destroy(inner, outer, start, stop, temp);
if err = one(inner); err != .None { return err; } if err = one(inner); err != nil { return err; }
if err = one(outer); err != .None { return err; } if err = one(outer); err != nil { return err; }
bits_used := int(_DIGIT_TYPE_BITS - intrinsics.count_leading_zeros(n)); bits_used := int(_DIGIT_TYPE_BITS - intrinsics.count_leading_zeros(n));
for i := bits_used; i >= 0; i -= 1 { for i := bits_used; i >= 0; i -= 1 {
start := (n >> (uint(i) + 1)) + 1 | 1; start := (n >> (uint(i) + 1)) + 1 | 1;
stop := (n >> uint(i)) + 1 | 1; stop := (n >> uint(i)) + 1 | 1;
if err = _int_recursive_product(temp, start, stop); err != .None { return err; } if err = _int_recursive_product(temp, start, stop); err != nil { return err; }
if err = mul(inner, inner, temp); err != .None { return err; } if err = mul(inner, inner, temp); err != nil { return err; }
if err = mul(outer, outer, inner); err != .None { return err; } if err = mul(outer, outer, inner); err != nil { return err; }
} }
shift := n - intrinsics.count_ones(n); 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) { int_choose_digit :: proc(res: ^Int, n, k: DIGIT) -> (err: Error) {
if res == nil { return .Invalid_Pointer; } 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); } 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{}; n_fac, k_fac, n_minus_k_fac := &Int{}, &Int{}, &Int{};
defer destroy(n_fac, k_fac, n_minus_k_fac); 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(n_minus_k_fac, n - k); err != nil { return err; }
if err = factorial(k_fac, k); err != .None { return err; } if err = factorial(k_fac, k); err != nil { return err; }
if err = mul(k_fac, k_fac, n_minus_k_fac); err != .None { 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 = factorial(n_fac, n); err != nil { return err; }
if err = div(res, n_fac, k_fac); err != .None { return err; } if err = div(res, n_fac, k_fac); err != nil { return err; }
return err; return err;
} }
@@ -886,7 +886,7 @@ _int_add :: proc(dest, a, b: ^Int) -> (err: Error) {
max_used = x.used; max_used = x.used;
old_used = dest.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; return err;
} }
dest.used = max_used + 1; 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) { _int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
dest := dest; x := number; y := decrease; dest := dest; x := number; y := decrease;
if err = clear_if_uninitialized(x); err != .None { if err = clear_if_uninitialized(x); err != nil {
return err; return err;
} }
if err = clear_if_uninitialized(y); err != .None { if err = clear_if_uninitialized(y); err != nil {
return err; return err;
} }
@@ -966,7 +966,7 @@ _int_sub :: proc(dest, number, decrease: ^Int) -> (err: Error) {
max_used := x.used; max_used := x.used;
i: int; 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; return err;
} }
dest.used = max_used; dest.used = max_used;
@@ -1042,7 +1042,7 @@ _int_mul :: proc(dest, a, b: ^Int, digits: int) -> (err: Error) {
t := &Int{}; 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; t.used = digits;
/* /*
@@ -1113,7 +1113,7 @@ _int_mul_comba :: proc(dest, a, b: ^Int, digits: int) -> (err: Error) {
/* /*
Grow the destination as required. 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. 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. 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; t.used = (2 * pa) + 1;
for ix = 0; ix < pa; ix += 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); b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3);
q := &Int{}; 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.used = numerator.used;
q.sign = numerator.sign; q.sign = numerator.sign;
@@ -1308,7 +1308,7 @@ _int_div_3 :: proc(quotient, numerator: ^Int) -> (remainder: int, err: Error) {
swap(q, quotient); swap(q, quotient);
} }
destroy(q); destroy(q);
return remainder, .None; return remainder, nil;
} }
/* /*
@@ -1320,26 +1320,26 @@ _int_div_small :: proc(quotient, remainder, numerator, denominator: ^Int) -> (er
c: int; c: int;
goto_end: for { 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); num_bits, _ := count_bits(numerator);
den_bits, _ := count_bits(denominator); den_bits, _ := count_bits(denominator);
n := num_bits - den_bits; n := num_bits - den_bits;
if err = abs(ta, numerator); err != .None { break goto_end; } if err = abs(ta, numerator); err != nil { break goto_end; }
if err = abs(tb, denominator); err != .None { break goto_end; } if err = abs(tb, denominator); err != nil { break goto_end; }
if err = shl(tb, tb, n); err != .None { break goto_end; } if err = shl(tb, tb, n); err != nil { break goto_end; }
if err = shl(tq, tq, n); err != .None { break goto_end; } if err = shl(tq, tq, n); err != nil { break goto_end; }
for n >= 0 { for n >= 0 {
if c, _ = cmp_mag(ta, tb); c == 0 || c == 1 { if c, _ = cmp_mag(ta, tb); c == 0 || c == 1 {
// ta -= tb // 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 // 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(tb, tb); err != nil { break goto_end; }
if err = shr1(tq, tq); err != .None { break goto_end; } if err = shr1(tq, tq); err != nil { break goto_end; }
n -= 1; n -= 1;
} }
@@ -1383,7 +1383,7 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
Quick outs. Quick outs.
*/ */
if denominator == 1 || numerator.used == 0 { if denominator == 1 || numerator.used == 0 {
err = .None; err = nil;
if quotient != nil { if quotient != nil {
err = copy(quotient, numerator); err = copy(quotient, numerator);
} }
@@ -1397,7 +1397,7 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
remainder = 1; remainder = 1;
} }
if quotient == nil { if quotient == nil {
return remainder, .None; return remainder, nil;
} }
return remainder, shr(quotient, numerator, 1); 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); remainder = int(numerator.digit[0]) & ((1 << uint(ix)) - 1);
if quotient == nil { if quotient == nil {
return remainder, .None; return remainder, nil;
} }
return remainder, shr(quotient, numerator, int(ix)); 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. 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.used = numerator.used;
q.sign = numerator.sign; q.sign = numerator.sign;
@@ -1448,42 +1448,42 @@ _int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT) -> (remain
swap(q, quotient); swap(q, quotient);
} }
destroy(q); destroy(q);
return remainder, .None; return remainder, nil;
} }
/* /*
Function computing both GCD and (if target isn't `nil`) also LCM. 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) { 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); az, _ := is_zero(a); bz, _ := is_zero(b);
if az && bz { if az && bz {
if res_gcd != nil { 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 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 { else if az {
if res_gcd != nil { 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 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 { else if bz {
if res_gcd != nil { 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 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); 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 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`. 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. GCD(0, 0) and LCM(0, 0) are both 0.
*/ */
if res_gcd != nil { 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 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 { } else if az {
/* /*
We can early out with GCD = B and LCM = 0 We can early out with GCD = B and LCM = 0
*/ */
if res_gcd != nil { 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 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 { } else if bz {
/* /*
We can early out with GCD = A and LCM = 0 We can early out with GCD = A and LCM = 0
*/ */
if res_gcd != nil { 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 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{}; 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{}; u, v := &Int{}, &Int{};
defer destroy(u, v); defer destroy(u, v);
if err = copy(u, a); err != .None { return err; } if err = copy(u, a); err != nil { return err; }
if err = copy(v, b); err != .None { return err; } if err = copy(v, b); err != nil { return err; }
/* /*
Must be positive for the remainder of the algorithm. 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. Divide the power of two out.
*/ */
if err = shr(u, u, k); err != .None { return err; } if err = shr(u, u, k); err != nil { return err; }
if err = shr(v, v, k); err != .None { return err; } if err = shr(v, v, k); err != nil { return err; }
} }
/* /*
Divide any remaining factors of two out. Divide any remaining factors of two out.
*/ */
if u_lsb != k { 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 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 { 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. 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. Divide out all factors of two.
*/ */
b, _ := count_lsb(v); 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. 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; 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 { if res_lcm == nil {
swap(temp_gcd_res, res_gcd); 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. 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); err = mul(res_lcm, res_lcm, b);
} else { } else {
/* /*
Store quotient in `t2` such that `t2 * a` is the LCM. 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); err = mul(res_lcm, res_lcm, b);
} }
+8 -2
View File
@@ -64,11 +64,18 @@ Int :: struct {
sign: Sign, sign: Sign,
}; };
Flag :: enum u8 {
NaN,
Inf,
Immutable,
};
Flags :: bit_set[Flag; u8];
/* /*
Errors are a strict superset of runtime.Allocation_Error. Errors are a strict superset of runtime.Allocation_Error.
*/ */
Error :: enum int { Error :: enum int {
None = 0,
Out_Of_Memory = 1, Out_Of_Memory = 1,
Invalid_Pointer = 2, Invalid_Pointer = 2,
Invalid_Argument = 3, Invalid_Argument = 3,
@@ -85,7 +92,6 @@ Error :: enum int {
}; };
Error_String :: #partial [Error]string{ Error_String :: #partial [Error]string{
.None = "None",
.Out_Of_Memory = "Out of memory", .Out_Of_Memory = "Out of memory",
.Invalid_Pointer = "Invalid pointer", .Invalid_Pointer = "Invalid pointer",
.Invalid_Argument = "Invalid argument", .Invalid_Argument = "Invalid argument",
+35 -35
View File
@@ -23,47 +23,47 @@ int_is_initialized :: proc(a: ^Int) -> bool {
} }
int_is_zero :: proc(a: ^Int) -> (res: bool, err: Error) { 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 false, err;
} }
return a.used == 0, .None; return a.used == 0, nil;
} }
int_is_positive :: proc(a: ^Int) -> (res: bool, err: Error) { 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 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) { 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 false, err;
} }
return a.sign == .Negative, .None; return a.sign == .Negative, nil;
} }
int_is_even :: proc(a: ^Int) -> (res: bool, err: Error) { 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; return false, err;
} }
res, err = is_zero(a); res, err = is_zero(a);
if err != .None { if err != nil {
return false, err; return false, err;
} else if res == true { } else if res == true {
return true, .None; return true, nil;
} }
res = false; res = false;
if a.used > 0 && a.digit[0] & 1 == 0 { if a.used > 0 && a.digit[0] & 1 == 0 {
res = true; res = true;
} }
return res, .None; return res, nil;
} }
int_is_odd :: proc(a: ^Int) -> (res: bool, err: Error) { 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; 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) { 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; return false, err;
} }
@@ -84,21 +84,21 @@ int_is_power_of_two :: proc(a: ^Int) -> (res: bool, err: Error) {
Early out for Int == 0. Early out for Int == 0.
*/ */
if a.used == 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. 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])) { 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. That was the only limb, so it's a power of two.
*/ */
if a.used == 1 { 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 { for i := 1; i < a.used; i += 1 {
if a.digit[i - 1] != 0 { if a.digit[i - 1] != 0 {
return false, .None; return false, nil;
} }
} }
return true, .None; return true, nil;
} }
/* /*
Compare two `Int`s, signed. Compare two `Int`s, signed.
*/ */
int_compare :: proc(a, b: ^Int) -> (res: int, err: Error) { 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; return 0, err;
} }
if err = clear_if_uninitialized(b); err != .None { if err = clear_if_uninitialized(b); err != nil {
return 0, err; return 0, err;
} }
neg: bool; neg: bool;
if neg, err = is_negative(a); err != .None { if neg, err = is_negative(a); err != nil {
return 0, err; return 0, err;
} }
/* Compare based on sign */ /* Compare based on sign */
if a.sign != b.sign { if a.sign != b.sign {
res = -1 if neg else +1; res = -1 if neg else +1;
return res, .None; return res, nil;
} }
/* If negative, compare in the opposite direction */ /* 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. 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) { 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; return 0, err;
} }
/* Compare based on sign */ /* Compare based on sign */
neg: bool; neg: bool;
if neg, err = is_neg(a); err != .None { if neg, err = is_neg(a); err != nil {
return 0, err; return 0, err;
} }
if neg { if neg {
return -1, .None; return -1, nil;
} }
/* Compare based on magnitude */ /* Compare based on magnitude */
if a.used > 1 { if a.used > 1 {
return +1, .None; return +1, nil;
} }
/* Compare the only digit in `a` to `u`. */ /* Compare the only digit in `a` to `u`. */
if a.digit[0] != u { if a.digit[0] != 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. Compare the magnitude of two `Int`s, unsigned.
*/ */
int_compare_magnitude :: proc(a, b: ^Int) -> (res: int, err: Error) { 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; return 0, err;
} }
if err = clear_if_uninitialized(b); err != .None { if err = clear_if_uninitialized(b); err != nil {
return 0, err; return 0, err;
} }
/* Compare based on used digits */ /* Compare based on used digits */
if a.used != b.used { if a.used != b.used {
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 */ /* Same number of used digits, compare based on their value */
for n := a.used - 1; n >= 0; n -= 1 { for n := a.used - 1; n >= 0; n -= 1 {
if a.digit[n] != b.digit[n] { if a.digit[n] != b.digit[n] {
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;
} }
+7 -4
View File
@@ -102,7 +102,7 @@ print :: proc(name: string, a: ^Int, base := i8(10), print_name := false, newlin
} else { } else {
fmt.printf("%v", as); fmt.printf("%v", as);
} }
if err != .None { if err != nil {
fmt.printf("%v (error: %v | %v)", name, err, a); fmt.printf("%v (error: %v | %v)", name, err, a);
} }
if newline { if newline {
@@ -118,19 +118,22 @@ demo :: proc() {
a, b, c, d, e, f := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}; a, b, c, d, e, f := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
defer destroy(a, b, c, d, e, f); defer destroy(a, b, c, d, e, f);
N :: 5_000; factorial(a, 128); // Untimed warmup.
N :: 128;
s := time.tick_now(); s := time.tick_now();
err = factorial(a, N); err = factorial(a, N);
Timings[.factorial].t += time.tick_since(s); Timings[.factorial].c += 1; 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); fmt.printf("factorial(%v) returned %v\n", N, err);
} }
s = time.tick_now(); s = time.tick_now();
as, err = itoa(a, 16); as, err = itoa(a, 16);
Timings[.itoa].t += time.tick_since(s); Timings[.itoa].c += 1; 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); fmt.printf("itoa(factorial(%v), 16) returned %v\n", N, err);
} }
+45 -45
View File
@@ -13,7 +13,7 @@ int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
if base < 2 || DIGIT(base) > _DIGIT_MAX { if base < 2 || DIGIT(base) > _DIGIT_MAX {
return -1, .Invalid_Argument; 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 n, _ := is_neg(a); n { return -1, .Math_Domain_Error; }
if z, _ := is_zero(a); z { 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) { int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
power := power; power := power;
if err = clear_if_uninitialized(base); err != .None { return err; } if err = clear_if_uninitialized(base); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; } if err = clear_if_uninitialized(dest); err != nil { return err; }
/* /*
Early outs. Early outs.
*/ */
@@ -48,7 +48,7 @@ int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
A zero base is a special case. A zero base is a special case.
*/ */
if power < 0 { if power < 0 {
if err = zero(dest); err != .None { return err; } if err = zero(dest); err != nil { return err; }
return .Math_Domain_Error; return .Math_Domain_Error;
} }
if power == 0 { return one(dest); } if power == 0 { return one(dest); }
@@ -77,19 +77,19 @@ int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
} }
g := &Int{}; g := &Int{};
if err = copy(g, base); err != .None { return err; } if err = copy(g, base); err != nil { return err; }
/* /*
Set initial result. 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 { loop: for power > 0 {
/* /*
If the bit is set, multiply. If the bit is set, multiply.
*/ */
if power & 1 != 0 { if power & 1 != 0 {
if err = mul(dest, g, dest); err != .None { if err = mul(dest, g, dest); err != nil {
break loop; break loop;
} }
} }
@@ -97,7 +97,7 @@ int_pow :: proc(dest, base: ^Int, power: int) -> (err: Error) {
Square. Square.
*/ */
if power > 1 { if power > 1 {
if err = sqr(g, g); err != .None { if err = sqr(g, g); err != nil {
break loop; break loop;
} }
} }
@@ -117,7 +117,7 @@ int_pow_int :: proc(dest: ^Int, base, power: int) -> (err: Error) {
base_t := &Int{}; base_t := &Int{};
defer destroy(base_t); 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); 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. Therefore, we return 0.
*/ */
if a < base { if a < base {
return 0, .None; return 0, nil;
} }
/* /*
If a number equals the base, the log is 1. If a number equals the base, the log is 1.
*/ */
if a == base { if a == base {
return 1, .None; return 1, nil;
} }
N := _WORD(a); N := _WORD(a);
@@ -199,14 +199,14 @@ int_log_digit :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
bracket_low = bracket_mid; bracket_low = bracket_mid;
} }
if N == bracket_mid { if N == bracket_mid {
return mid, .None; return mid, nil;
} }
} }
if bracket_high == N { if bracket_high == N {
return high, .None; return high, nil;
} else { } 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) { int_sqrt :: proc(dest, src: ^Int) -> (err: Error) {
when true { when true {
if err = clear_if_uninitialized(dest); err != .None { return err; } if err = clear_if_uninitialized(dest); err != nil { return err; }
if err = clear_if_uninitialized(src); err != .None { return err; } if err = clear_if_uninitialized(src); err != nil { return err; }
/* Must be positive. */ /* Must be positive. */
if src.sign == .Negative { return .Invalid_Argument; } 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); defer destroy(x, y, t1, t2);
count: int; 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; 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 { for {
/* /*
@@ -245,7 +245,7 @@ int_sqrt :: proc(dest, src: ^Int) -> (err: Error) {
if c, _ := cmp(y, x); c == 0 || c == 1 { if c, _ := cmp(y, x); c == 0 || c == 1 {
swap(dest, x); swap(dest, x);
return .None; return nil;
} }
swap(x, y); 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); } if n == 2 { return sqrt(dest, src); }
/* Initialize dest + src if needed. */ /* Initialize dest + src if needed. */
if err = clear_if_uninitialized(dest); err != .None { return err; } if err = clear_if_uninitialized(dest); err != nil { return err; }
if err = clear_if_uninitialized(src); err != .None { return err; } if err = clear_if_uninitialized(src); err != nil { return err; }
if n < 0 || n > int(_DIGIT_MAX) { if n < 0 || n > int(_DIGIT_MAX) {
return .Invalid_Argument; return .Invalid_Argument;
@@ -280,7 +280,7 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
neg: bool; neg: bool;
if n & 1 == 0 { 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. */ /* 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. */ /* Start value must be larger than root. */
ilog2 += 2; 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; c: int;
iterations := 0; iterations := 0;
for { for {
/* t1 = t2 */ /* 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))) */ /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
/* t3 = 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 */ /* numerator */
/* t2 = t1**b */ /* 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 */ /* 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 */ /* denominator */
/* t3 = t1**(b-1) * b */ /* 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)) */ /* t3 = (t1**b - a)/(b * t1**(b-1)) */
if err = div(t3, t2, t3); err != .None { return err; } if err = div(t3, t2, t3); err != nil { return err; }
if err = sub(t2, t1, t3); err != .None { 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 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; iterations = 0;
for { 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); c, err = cmp(t2, a);
if c == 0 { if c == 0 {
swap(dest, t1); swap(dest, t1);
return .None; return nil;
} else if c == -1 { } 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 { } else {
break; break;
} }
@@ -391,11 +391,11 @@ int_root_n :: proc(dest, src: ^Int, n: int) -> (err: Error) {
iterations = 0; iterations = 0;
/* Correct overshoot from above or from recurrence. */ /* Correct overshoot from above or from recurrence. */
for { 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); c, err = cmp(t2, a);
if c == 1 { 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 { } else {
break; break;
} }
@@ -424,13 +424,13 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
ic, _ := cmp(a, base); ic, _ := cmp(a, base);
if ic == -1 || ic == 0 { 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 = set(bi_base, base); err != nil { return -1, err; }
if err = init_multi(bracket_mid, t); err != .None { return -1, err; } if err = init_multi(bracket_mid, t); err != nil { return -1, err; }
if err = one(bracket_low); err != .None { return -1, err; } if err = one(bracket_low); err != nil { return -1, err; }
if err = set(bracket_high, base); err != .None { return -1, err; } if err = set(bracket_high, base); err != nil { return -1, err; }
low := 0; high := 1; low := 0; high := 1;
@@ -450,12 +450,12 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
} }
low = high; 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); destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err; return -1, err;
} }
high <<= 1; 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); destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err; return -1, err;
} }
@@ -464,12 +464,12 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
for (high - low) > 1 { for (high - low) > 1 {
mid := (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); destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err; 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); destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return -1, err; return -1, err;
} }
@@ -484,7 +484,7 @@ _int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
} }
if mc == 0 { if mc == 0 {
destroy(bracket_low, bracket_high, bracket_mid, t, bi_base); destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
return mid, .None; return mid, nil;
} }
} }
+45 -45
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) int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator := context.allocator) -> (err: Error)
where intrinsics.type_is_integer(T) { where intrinsics.type_is_integer(T) {
src := src; src := src;
if err = clear_if_uninitialized(dest); err != .None { if err = clear_if_uninitialized(dest); err != nil {
return err; return err;
} }
dest.used = 0; dest.used = 0;
@@ -48,7 +48,7 @@ int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator :
src >>= _DIGIT_BITS; src >>= _DIGIT_BITS;
} }
_zero_unused(dest); _zero_unused(dest);
return .None; return nil;
} }
set :: proc { int_set_from_integer, int_copy }; 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. Copy one `Int` to another.
*/ */
int_copy :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) { 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, do nothing
*/ */
if (dest == src) { if (dest == src) {
return .None; return nil;
} }
/* /*
Grow `dest` to fit `src`. Grow `dest` to fit `src`.
If `dest` is not yet initialized, it will be using `allocator`. 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; return err;
} }
@@ -81,7 +81,7 @@ int_copy :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error
dest.used = src.used; dest.used = src.used;
dest.sign = src.sign; dest.sign = src.sign;
_zero_unused(dest); _zero_unused(dest);
return .None; return nil;
} }
copy :: proc { int_copy, }; copy :: proc { int_copy, };
@@ -106,7 +106,7 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
/* /*
Check that src is usable. Check that src is usable.
*/ */
if err = clear_if_uninitialized(src); err != .None { if err = clear_if_uninitialized(src); err != nil {
return err; return err;
} }
/* /*
@@ -114,13 +114,13 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
*/ */
if (dest == src) { if (dest == src) {
dest.sign = .Zero_or_Positive; dest.sign = .Zero_or_Positive;
return .None; return nil;
} }
/* /*
Copy `src` to `dest` Copy `src` to `dest`
*/ */
if err = copy(dest, src, allocator); err != .None { if err = copy(dest, src, allocator); err != nil {
return err; return err;
} }
@@ -128,7 +128,7 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
Fix sign. Fix sign.
*/ */
dest.sign = .Zero_or_Positive; dest.sign = .Zero_or_Positive;
return .None; return nil;
} }
platform_abs :: proc(n: $T) -> T where intrinsics.type_is_integer(T) { 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. Check that src is usable.
*/ */
if err = clear_if_uninitialized(src); err != .None { if err = clear_if_uninitialized(src); err != nil {
return err; return err;
} }
/* /*
@@ -158,12 +158,12 @@ neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
} }
if (dest == src) { if (dest == src) {
dest.sign = sign; dest.sign = sign;
return .None; return nil;
} }
/* /*
Copy `src` to `dest` Copy `src` to `dest`
*/ */
if err = copy(dest, src, allocator); err != .None { if err = copy(dest, src, allocator); err != nil {
return err; return err;
} }
@@ -171,7 +171,7 @@ neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
Fix sign. Fix sign.
*/ */
dest.sign = 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. Check that `a`is usable.
*/ */
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return 0, err; 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))); 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. Check that `a`is usable.
*/ */
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return 0, err; 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 { for shift := 0; shift < count; shift += 1 {
o := offset + shift; o := offset + shift;
v, e = extract_bit(a, o); v, e = extract_bit(a, o);
if e != .None { if e != nil {
break; break;
} }
res = res + _WORD(v) << uint(shift); 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); res |= _WORD(r);
} }
return res, .None; return res, nil;
} }
} }
@@ -276,7 +276,7 @@ shrink :: proc(a: ^Int) -> (err: Error) {
if a.used != needed { if a.used != needed {
return grow(a, needed); return grow(a, needed);
} }
return .None; return nil;
} }
int_grow :: proc(a: ^Int, digits: int, allow_shrink := false, allocator := context.allocator) -> (err: Error) { 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 { if len(a.digit) != needed {
return .Out_Of_Memory; return .Out_Of_Memory;
} }
return .None; return nil;
} }
grow :: proc { int_grow, }; grow :: proc { int_grow, };
@@ -337,12 +337,12 @@ zero :: clear;
Set the `Int` to 1 and optionally shrink it to the minimum backing size. 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) { 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.used = 1;
a.digit[0] = 1; a.digit[0] = 1;
a.sign = .Zero_or_Positive; a.sign = .Zero_or_Positive;
return .None; return nil;
} }
one :: proc { int_one, }; 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. 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) { 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; return err;
} }
a.used = 1; a.used = 1;
a.digit[0] = 1; a.digit[0] = 1;
a.sign = .Negative; a.sign = .Negative;
return .None; return nil;
} }
minus_one :: proc { int_minus_one, }; 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. Grow to accomodate the single bit.
*/ */
a.used = (power / _DIGIT_BITS) + 1; a.used = (power / _DIGIT_BITS) + 1;
if err = grow(a, a.used); err != .None { if err = grow(a, a.used); err != nil {
return err; return err;
} }
/* /*
@@ -389,7 +389,7 @@ power_of_two :: proc(a: ^Int, power: int) -> (err: Error) {
Set the bit. Set the bit.
*/ */
a.digit[power / _DIGIT_BITS] = 1 << uint((power % _DIGIT_BITS)); a.digit[power / _DIGIT_BITS] = 1 << uint((power % _DIGIT_BITS));
return .None; return nil;
} }
int_get_u128 :: proc(a: ^Int) -> (res: u128, err: Error) { 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? 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) { 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); size_in_bits := int(size_of(T) * 8);
i := int((size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS); 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, }; get :: proc { int_get, };
int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) { 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; return 0, err;
} }
@@ -478,14 +478,14 @@ int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) {
Count bits in an `Int`. Count bits in an `Int`.
*/ */
count_bits :: proc(a: ^Int) -> (count: int, err: Error) { 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; return 0, err;
} }
/* /*
Fast path for zero. Fast path for zero.
*/ */
if z, _ := is_zero(a); z { if z, _ := is_zero(a); z {
return 0, .None; return 0, nil;
} }
/* /*
Get the number of DIGITs and use it. 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. Differs from regular `ctz` in that 0 returns 0.
*/ */
int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) { 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; _ctz :: intrinsics.count_trailing_zeros;
/* /*
Easy out. 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. Scan lower digits until non-zero.
@@ -520,7 +520,7 @@ int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {
q := a.digit[x]; q := a.digit[x];
x *= _DIGIT_BITS; 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) 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; 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 { for i := 0; i < digits; i += 1 {
dest.digit[i] = int_random_digit(r) & _MASK; 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.digit[digits - 1] &= ((1 << uint(bits)) - 1);
} }
dest.used = digits; dest.used = digits;
return .None; return nil;
} }
rand :: proc { int_rand, }; rand :: proc { int_rand, };
@@ -597,7 +597,7 @@ clear_if_uninitialized_multi :: proc(args: ..^Int) -> (err: Error) {
for i in args { for i in args {
if i != nil && !is_initialized(i) { if i != nil && !is_initialized(i) {
e := grow(i, _DEFAULT_DIGIT_COUNT); e := grow(i, _DEFAULT_DIGIT_COUNT);
if e != .None { err = e; } if e != nil { err = e; }
} }
} }
return err; 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) { int_init_multi :: proc(integers: ..^Int) -> (err: Error) {
integers := integers; integers := integers;
for a in &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, }; init_multi :: proc { int_init_multi, };
_copy_digits :: proc(dest, src: ^Int, digits: int) -> (err: Error) { _copy_digits :: proc(dest, src: ^Int, digits: int) -> (err: Error) {
digits := digits; digits := digits;
if err = clear_if_uninitialized(src); err != .None { return err; } if err = clear_if_uninitialized(src); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; } if err = clear_if_uninitialized(dest); err != nil { return err; }
/* /*
If dest == src, do nothing If dest == src, do nothing
*/ */
if (dest == src) { if (dest == src) {
return .None; return nil;
} }
digits = min(digits, len(src.digit), len(dest.digit)); digits = min(digits, len(src.digit), len(dest.digit));
mem.copy_non_overlapping(&dest.digit[0], &src.digit[0], size_of(DIGIT) * digits); 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. Typically very fast. Also fixes the sign if there are no more leading digits.
*/ */
clamp :: proc(a: ^Int) -> (err: Error) { clamp :: proc(a: ^Int) -> (err: Error) {
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return err; return err;
} }
for a.used > 0 && a.digit[a.used - 1] == 0 { 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 { if z, _ := is_zero(a); z {
a.sign = .Zero_or_Positive; a.sign = .Zero_or_Positive;
} }
return .None; return nil;
} }
+26 -26
View File
@@ -24,13 +24,13 @@ import "core:mem"
2's complement `and`, returns `dest = a & b;` 2's complement `and`, returns `dest = a & b;`
*/ */
int_and :: proc(dest, a, b: ^Int) -> (err: Error) { 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; used := max(a.used, b.used) + 1;
/* /*
Grow the destination to accomodate the result. 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_a, _ := is_neg(a);
neg_b, _ := is_neg(b); neg_b, _ := is_neg(b);
@@ -85,12 +85,12 @@ and :: proc { int_add, };
2's complement `or`, returns `dest = a | b;` 2's complement `or`, returns `dest = a | b;`
*/ */
int_or :: proc(dest, a, b: ^Int) -> (err: Error) { 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; used := max(a.used, b.used) + 1;
/* /*
Grow the destination to accomodate the result. 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_a, _ := is_neg(a);
neg_b, _ := is_neg(b); neg_b, _ := is_neg(b);
@@ -145,13 +145,13 @@ or :: proc { int_or, };
2's complement `xor`, returns `dest = a ~ b;` 2's complement `xor`, returns `dest = a ~ b;`
*/ */
int_xor :: proc(dest, a, b: ^Int) -> (err: Error) { 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; used := max(a.used, b.used) + 1;
/* /*
Grow the destination to accomodate the result. 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_a, _ := is_neg(a);
neg_b, _ := is_neg(b); 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`. 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. Temporarily fix sign.
@@ -235,25 +235,25 @@ complement :: proc { int_complement, };
*/ */
int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int) -> (err: Error) { int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int) -> (err: Error) {
bits := bits; 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 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.) Shift right by a certain bit count (store quotient and optional remainder.)
`numerator` should not be used after this. `numerator` should not be used after this.
*/ */
if remainder != nil { 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. Shift by as many digits in the bit count.
*/ */
if bits >= _DIGIT_BITS { 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. 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. 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. Shift right by a certain bit count with sign extension.
*/ */
int_shr_signed :: proc(dest, src: ^Int, bits: int) -> (err: Error) { 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(src); err != nil { return err; }
if err = clear_if_uninitialized(dest); err != .None { return err; } if err = clear_if_uninitialized(dest); err != nil { return err; }
if src.sign == .Zero_or_Positive { if src.sign == .Zero_or_Positive {
return shr(dest, src, bits); 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)); 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) { int_shl :: proc(dest, src: ^Int, bits: int) -> (err: Error) {
bits := bits; 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 { if bits < 0 {
return .Invalid_Argument; 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. Grow `dest` to accommodate the additional bits.
*/ */
digits_needed := dest.used + (bits / _DIGIT_BITS) + 1; 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; dest.used = digits_needed;
/* /*
Shift by as many digits in the bit count as we have. Shift by as many digits in the bit count as we have.
*/ */
if bits >= _DIGIT_BITS { 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. 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. No need to shift a zero.
*/ */
z: bool; 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. 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. 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; quotient.used += digits;
mem.zero_slice(quotient.digit[:digits]); mem.zero_slice(quotient.digit[:digits]);
return .None; return nil;
} }
shl_digit :: proc { int_shl_digit, }; shl_digit :: proc { int_shl_digit, };
+25 -25
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) { int_itoa_string :: proc(a: ^Int, radix := i8(-1), zero_terminate := false, allocator := context.allocator) -> (res: string, err: Error) {
a := a; radix := radix; a := a; radix := radix;
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return "", err; 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. 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; 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) { int_itoa_cstring :: proc(a: ^Int, radix := i8(-1), allocator := context.allocator) -> (res: cstring, err: Error) {
a := a; radix := radix; a := a; radix := radix;
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return "", err; 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) { 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; 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; 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. We weren't given a size. Let's compute it.
*/ */
if size == -1 { 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; 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; diff := size - written;
mem.copy(&buffer[0], &buffer[diff], 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; diff := size - written;
mem.copy(&buffer[0], &buffer[diff], 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 { for offset := 0; offset < count; offset += shift {
bits_to_get := int(min(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; return len(buffer) - available, .Invalid_Argument;
} }
available -= 1; available -= 1;
@@ -222,7 +222,7 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
diff := size - written; diff := size - written;
mem.copy(&buffer[0], &buffer[diff], written); mem.copy(&buffer[0], &buffer[diff], written);
} }
return written, .None; return written, nil;
} }
return _itoa_raw_full(a, radix, buffer, zero_terminate); 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. 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. We'll interpret an empty string as zero.
*/ */
if len(input) == 0 { if len(input) == 0 {
return .None; return nil;
} }
/* /*
@@ -295,8 +295,8 @@ int_atoi :: proc(res: ^Int, input: string, radix: i8) -> (err: Error) {
break; break;
} }
if err = mul(res, res, DIGIT(radix)); err != .None { return err; } if err = mul(res, res, DIGIT(radix)); err != nil { return err; }
if err = add(res, res, DIGIT(y)); err != .None { return err; } if err = add(res, res, DIGIT(y)); err != nil { return err; }
input = input[1:]; input = input[1:];
} }
@@ -313,7 +313,7 @@ int_atoi :: proc(res: ^Int, input: string, radix: i8) -> (err: Error) {
res.sign = sign; 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 { if radix < 2 || radix > 64 {
return -1, .Invalid_Argument; return -1, .Invalid_Argument;
} }
if err = clear_if_uninitialized(a); err != .None { if err = clear_if_uninitialized(a); err != nil {
return 0, err; return 0, err;
} }
if z, _ := is_zero(a); z { if z, _ := is_zero(a); z {
if zero_terminate { if zero_terminate {
return 2, .None; return 2, nil;
} }
return 1, .None; return 1, nil;
} }
if pot, _ := is_power_of_two(a); pot { 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, digit = a.digit,
}; };
if size, err = log(t, DIGIT(radix)); err != .None { if size, err = log(t, DIGIT(radix)); err != nil {
return 0, err; return 0, err;
} }
} else { } else {
@@ -364,8 +364,8 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false) -> (size: int, e
err = set(k, lb[radix]); err = set(k, lb[radix]);
/* n = floor((la * k) / 2^29) + 1 */ /* n = floor((la * k) / 2^29) + 1 */
if err = mul(k, la, k); 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 != .None { 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" */ /* The "+1" here is the "+1" in "floor((la * k) / 2^29) + 1" */
/* n = n + 1 + EOS + sign */ /* 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 += 2 if a.sign == .Negative else 1;
size += 1 if zero_terminate else 0; 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) { _itoa_raw_full :: proc(a: ^Int, radix: i8, buffer: []u8, zero_terminate := false) -> (written: int, err: Error) {
temp, denominator := &Int{}, &Int{}; temp, denominator := &Int{}, &Int{};
if err = copy(temp, a); err != .None { return 0, err; } if err = copy(temp, a); err != nil { return 0, err; }
if err = set(denominator, radix); err != .None { return 0, err; } if err = set(denominator, radix); err != nil { return 0, err; }
available := len(buffer); available := len(buffer);
if zero_terminate { if zero_terminate {
@@ -450,7 +450,7 @@ _itoa_raw_full :: proc(a: ^Int, radix: i8, buffer: []u8, zero_terminate := false
remainder: int; remainder: int;
for { 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); destroy(temp, denominator);
return len(buffer) - available, err; 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; diff := len(buffer) - written;
mem.copy(&buffer[0], &buffer[diff], written); mem.copy(&buffer[0], &buffer[diff], written);
} }
return written, .None; return written, nil;
} }
+69 -69
View File
@@ -33,14 +33,14 @@ PyRes :: struct {
aa, bb, sum := &Int{}, &Int{}, &Int{}; aa, bb, sum := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, sum); 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(aa, string(a), 16); err != nil { 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 = atoi(bb, string(b), 16); err != nil { 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 = add(sum, aa, bb); err != nil { return PyRes{res=":add:add(sum,a,b):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(sum, 16, context.temp_allocator); r, err = int_itoa_cstring(sum, 16, context.temp_allocator);
if err != .None { return PyRes{res=":add:itoa(sum):", err=err}; } if err != nil { return PyRes{res=":add:itoa(sum):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
@export test_sub :: proc "c" (a, b: cstring) -> (res: PyRes) { @export test_sub :: proc "c" (a, b: cstring) -> (res: PyRes) {
@@ -50,14 +50,14 @@ PyRes :: struct {
aa, bb, sum := &Int{}, &Int{}, &Int{}; aa, bb, sum := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, sum); 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(aa, string(a), 16); err != nil { 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 = atoi(bb, string(b), 16); err != nil { 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 = sub(sum, aa, bb); err != nil { return PyRes{res=":sub:sub(sum,a,b):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(sum, 16, context.temp_allocator); r, err = int_itoa_cstring(sum, 16, context.temp_allocator);
if err != .None { return PyRes{res=":sub:itoa(sum):", err=err}; } if err != nil { return PyRes{res=":sub:itoa(sum):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
@export test_mul :: proc "c" (a, b: cstring) -> (res: PyRes) { @export test_mul :: proc "c" (a, b: cstring) -> (res: PyRes) {
@@ -67,14 +67,14 @@ PyRes :: struct {
aa, bb, product := &Int{}, &Int{}, &Int{}; aa, bb, product := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, product); 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(aa, string(a), 16); err != nil { 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 = atoi(bb, string(b), 16); err != nil { 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 = mul(product, aa, bb); err != nil { return PyRes{res=":mul:mul(product,a,b):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(product, 16, context.temp_allocator); r, err = int_itoa_cstring(product, 16, context.temp_allocator);
if err != .None { return PyRes{res=":mul:itoa(product):", err=err}; } if err != nil { return PyRes{res=":mul:itoa(product):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -87,14 +87,14 @@ PyRes :: struct {
aa, bb, quotient := &Int{}, &Int{}, &Int{}; aa, bb, quotient := &Int{}, &Int{}, &Int{};
defer destroy(aa, bb, quotient); 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(aa, string(a), 16); err != nil { 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 = atoi(bb, string(b), 16); err != nil { 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 = div(quotient, aa, bb); err != nil { return PyRes{res=":div:div(quotient,a,b):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(quotient, 16, context.temp_allocator); r, err = int_itoa_cstring(quotient, 16, context.temp_allocator);
if err != .None { return PyRes{res=":div:itoa(quotient):", err=err}; } if err != nil { return PyRes{res=":div:itoa(quotient):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
@@ -109,8 +109,8 @@ PyRes :: struct {
aa := &Int{}; aa := &Int{};
defer destroy(aa); defer destroy(aa);
if err = atoi(aa, string(a), 16); err != .None { return PyRes{res=":log:atoi(a):", 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 != .None { return PyRes{res=":log:log(a, base):", err=err}; } if l, err = log(aa, base); err != nil { return PyRes{res=":log:log(a, base):", err=err}; }
zero(aa); zero(aa);
aa.digit[0] = DIGIT(l) & _MASK; aa.digit[0] = DIGIT(l) & _MASK;
@@ -120,8 +120,8 @@ PyRes :: struct {
r: cstring; r: cstring;
r, err = int_itoa_cstring(aa, 16, context.temp_allocator); r, err = int_itoa_cstring(aa, 16, context.temp_allocator);
if err != .None { return PyRes{res=":log:itoa(res):", err=err}; } if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -134,13 +134,13 @@ PyRes :: struct {
dest, bb := &Int{}, &Int{}; dest, bb := &Int{}, &Int{};
defer destroy(dest, bb); defer destroy(dest, bb);
if err = atoi(bb, string(base), 16); err != .None { return PyRes{res=":pow:atoi(base):", 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 != .None { return PyRes{res=":pow:pow(dest, base, power):", err=err}; } if err = pow(dest, bb, power); err != nil { return PyRes{res=":pow:pow(dest, base, power):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator); r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":log:itoa(res):", err=err}; } if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -153,13 +153,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":sqrt:atoi(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 != .None { return PyRes{res=":sqrt:sqrt(src):", err=err}; } if err = sqrt(src, src); err != nil { return PyRes{res=":sqrt:sqrt(src):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":log:itoa(res):", err=err}; } if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -172,13 +172,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":root_n:atoi(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 != .None { return PyRes{res=":root_n:root_n(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: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":root_n:itoa(res):", err=err}; } if err != nil { return PyRes{res=":root_n:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -191,13 +191,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shr_digit:atoi(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 != .None { return PyRes{res=":shr_digit:shr_digit(src):", err=err}; } if err = shr_digit(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shr_digit:itoa(res):", err=err}; } if err != nil { return PyRes{res=":shr_digit:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -210,13 +210,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shl_digit:atoi(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 != .None { return PyRes{res=":shl_digit:shr_digit(src):", err=err}; } if err = shl_digit(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shl_digit:itoa(res):", err=err}; } if err != nil { return PyRes{res=":shl_digit:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -229,13 +229,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shr:atoi(src):", 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 != .None { return PyRes{res=":shr:shr(src, bits):", err=err}; } if err = shr(src, src, bits); err != nil { return PyRes{res=":shr:shr(src, bits):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shr:itoa(res):", err=err}; } if err != nil { return PyRes{res=":shr:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -248,13 +248,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shr_signed:atoi(src):", 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 != .None { return PyRes{res=":shr_signed:shr_signed(src, bits):", 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: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shr_signed:itoa(res):", err=err}; } if err != nil { return PyRes{res=":shr_signed:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -267,13 +267,13 @@ PyRes :: struct {
src := &Int{}; src := &Int{};
defer destroy(src); defer destroy(src);
if err = atoi(src, string(source), 16); err != .None { return PyRes{res=":shl:atoi(src):", 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 != .None { return PyRes{res=":shl:shl(src, bits):", err=err}; } if err = shl(src, src, bits); err != nil { return PyRes{res=":shl:shl(src, bits):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(src, 16, context.temp_allocator); r, err = int_itoa_cstring(src, 16, context.temp_allocator);
if err != .None { return PyRes{res=":shl:itoa(res):", err=err}; } if err != nil { return PyRes{res=":shl:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -286,12 +286,12 @@ PyRes :: struct {
dest := &Int{}; dest := &Int{};
defer destroy(dest); 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: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator); r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":factorial:itoa(res):", err=err}; } if err != nil { return PyRes{res=":factorial:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -304,14 +304,14 @@ PyRes :: struct {
ai, bi, dest := &Int{}, &Int{}, &Int{}; ai, bi, dest := &Int{}, &Int{}, &Int{};
defer destroy(ai, bi, dest); 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(ai, string(a), 16); err != nil { 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 = atoi(bi, string(b), 16); err != nil { 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 = gcd(dest, ai, bi); err != nil { return PyRes{res=":gcd:gcd(a, b):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator); r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":gcd:itoa(res):", err=err}; } if err != nil { return PyRes{res=":gcd:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }
/* /*
@@ -324,13 +324,13 @@ PyRes :: struct {
ai, bi, dest := &Int{}, &Int{}, &Int{}; ai, bi, dest := &Int{}, &Int{}, &Int{};
defer destroy(ai, bi, dest); 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(ai, string(a), 16); err != nil { 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 = atoi(bi, string(b), 16); err != nil { 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 = lcm(dest, ai, bi); err != nil { return PyRes{res=":lcm:lcm(a, b):", err=err}; }
r: cstring; r: cstring;
r, err = int_itoa_cstring(dest, 16, context.temp_allocator); r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
if err != .None { return PyRes{res=":lcm:itoa(res):", err=err}; } if err != nil { return PyRes{res=":lcm:itoa(res):", err=err}; }
return PyRes{res = r, err = .None}; return PyRes{res = r, err = nil};
} }