mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 20:58:15 +00:00
big: Error.None -> nil
This commit is contained in:
+108
-108
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user