Arbitrary precision integers and rationals.

Collection Info

View Source
Collection
core
Path
math/big
Entries
543

Source Files

Constants

6

Error_String #

Source
Error_String :: #sparse[Error]string{.None = "None", .Out_Of_Memory = "Out of memory", .Invalid_Pointer = "Invalid pointer", .Invalid_Argument = "Invalid argument", .Mode_Not_Implemented = "Allocation mode not implemented", .Assignment_To_Immutable = "Assignment to immutable", .Max_Iterations_Reached = "Max iterations reached", .Buffer_Overflow = "Buffer overflow", .Integer_Overflow = "Integer overflow", .Integer_Underflow = "Integer underflow", .Division_by_Zero = "Division by zero", .Math_Domain_Error = "Math domain error", .Cannot_Open_File = "Cannot_Open_File", .Cannot_Read_File = "Cannot_Read_File", .Cannot_Write_File = "Cannot_Write_File", .Unimplemented = "Unimplemented"}

ITOA_DIVISOR #

Source
ITOA_DIVISOR :: DIGIT(1_000_000_000_000_000_000)

Base 10 extraction constants

MATH_BIG_USE_FROBENIUS_TEST #

Source
MATH_BIG_USE_FROBENIUS_TEST :: !MATH_BIG_USE_LUCAS_SELFRIDGE_TEST

MATH_BIG_USE_LUCAS_SELFRIDGE_TEST #

Source
MATH_BIG_USE_LUCAS_SELFRIDGE_TEST :: #config(MATH_BIG_USE_LUCAS_SELFRIDGE_TEST, false)

`internal_int_is_prime` switchables. Use Frobenius-Underwood for primality testing, or use Lucas-Selfridge (default).

Config Values

1

MATH_BIG_USE_LUCAS_SELFRIDGE_TEST #

Source
MATH_BIG_USE_LUCAS_SELFRIDGE_TEST :: #config(MATH_BIG_USE_LUCAS_SELFRIDGE_TEST, false)

`internal_int_is_prime` switchables. Use Frobenius-Underwood for primality testing, or use Lucas-Selfridge (default).

Types

11

Procedures

318

assert_if_nil_int #

Source
assert_if_nil_int :: proc(integers: ..^Int, loc := #caller_location) {…}

assert_if_nil_rat #

Source
assert_if_nil_rat :: proc(rationals: ..^Rat, loc := #caller_location) {…}

assert_initialized #

Source
assert_initialized :: proc(a: ^Int, loc := #caller_location) {…}

Internal helpers.

clamp #

Source
clamp :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {…}

Trim unused digits. This is used to ensure that leading zero digits are trimmed and the leading "used" digit will be non-zero. Typically very fast. Also fixes the sign if there are no more leading digits.

clear_if_uninitialized_multi #

Source
clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocator) -> (err: Error) {…}

clear_if_uninitialized_single #

Source
clear_if_uninitialized_single :: proc(arg: ^Int, allocator := context.allocator) -> (err: Error) {…}

combinations_with_repetition #

Source
combinations_with_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {…}

With `n` items, calculate how many ways that `r` of them can be chosen. Also known as the multiset coefficient or (n multichoose k).

combinations_without_repetition #

Source
combinations_without_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {…}

With `n` items, calculate how many ways that `r` of them can be chosen without any repeats. Also known as the binomial coefficient or (n choose k).

copy_digits #

Source
copy_digits :: proc(dest, src: ^Int, digits: int, offset: int = int(0), allocator := context.allocator) -> (err: Error) {…}

count_bits #

Source
count_bits :: proc(a: ^Int, allocator := context.allocator) -> (count: int, err: Error) {…}

Count bits in an `Int`.

ilog2 #

Source
ilog2 :: proc(value: $T) -> (log2: $$deferred_return) {…}

int_abs #

Source
int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

Set `dest` to |`src`|.

int_add #

Source
int_add :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

High-level addition. Handles sign.

int_add_digit #

Source
int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {…}

Adds the unsigned `DIGIT` immediate to an `Int`, such that the `DIGIT` doesn't have to be turned into an `Int` first. dest = a + digit;

int_addmod #

Source
int_addmod :: proc(remainder, number, addend, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number + addend) % modulus.

int_atoi #

Source
int_atoi :: proc(res: ^Int, input: string, radix: i8 = i8(10), allocator := context.allocator) -> (err: Error) {…}

Read a string [ASCII] in a given radix.

int_bit_and #

Source
int_bit_and :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

2's complement `and`, returns `dest = a & b;`

int_bit_complement #

Source
int_bit_complement :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

dest = ~src

int_bit_or #

Source
int_bit_or :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

2's complement `or`, returns `dest = a | b;`

int_bit_xor #

Source
int_bit_xor :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

2's complement `xor`, returns `dest = a ^ b;`

int_bitfield_extract #

Source
int_bitfield_extract :: proc(a: ^Int, offset, count: int, allocator := context.allocator) -> (res: _WORD, err: Error) {…}

int_bitfield_extract_single #

Source
int_bitfield_extract_single :: proc(a: ^Int, offset: int, allocator := context.allocator) -> (bit: _WORD, err: Error) {…}

Helpers to extract values from the `Int`.

int_choose_digit #

Source
int_choose_digit :: proc(res: ^Int, n, k: int, allocator := context.allocator) -> (err: Error) {…}

Number of ways to choose `k` items from `n` items. Also known as the binomial coefficient. TODO: Speed up. Could be done faster by reusing code from factorial and reusing the common "prefix" results for n!, k! and n-k! We know that n >= k, otherwise we early out with res = 0. So: n-k, keep result n, start from previous result k, start from previous result

int_clear #

Source
int_clear :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Clear `Int` and resize it to the default size.

int_cmp #

Source
int_cmp :: proc(a, b: ^Int, allocator := context.allocator) -> (comparison: int, err: Error) {…}

Compare two `Int`s, signed.

int_cmp_digit #

Source
int_cmp_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (comparison: int, err: Error) {…}

Compare an `Int` to an unsigned number upto the size of the backing type.

int_cmp_mag #

Source
int_cmp_mag :: proc(a, b: ^Int, allocator := context.allocator) -> (res: int, err: Error) {…}

Compare the magnitude of two `Int`s, unsigned.

int_compare #

Source
int_compare :: proc(a, b: ^Int, allocator := context.allocator) -> (comparison: int, err: Error) {…}

Compare two `Int`s, signed.

int_compare_digit #

Source
int_compare_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (comparison: int, err: Error) {…}

Compare an `Int` to an unsigned number upto the size of the backing type.

int_compare_magnitude #

Source
int_compare_magnitude :: proc(a, b: ^Int, allocator := context.allocator) -> (res: int, err: Error) {…}

Compare the magnitude of two `Int`s, unsigned.

int_copy #

Source
int_copy :: proc(dest, src: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Copy one `Int` to another.

int_count_lsb #

Source
int_count_lsb :: proc(a: ^Int, allocator := context.allocator) -> (count: int, err: Error) {…}

Returns the number of trailing zeroes before the first one. Differs from regular `ctz` in that 0 returns 0.

int_destroy #

Source
int_destroy :: proc(integers: ..^Int) {…}

Deallocates the backing memory of one or more `Int`s.

int_div #

Source
int_div :: proc(quotient, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {…}

int_div_digit #

Source
int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (err: Error) {…}

int_divmod #

Source
int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {…}

divmod. Both the quotient and remainder are optional and may be passed a nil.

int_divmod_digit #

Source
int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {…}

int_double #

Source
int_double :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

dest = src * 2 dest = src << 1

int_equals #

Source
int_equals :: proc(a, b: ^Int, allocator := context.allocator) -> (equals: bool, err: Error) {…}

bool := a == b

int_equals_abs #

Source
int_equals_abs :: proc(a, b: ^Int, allocator := context.allocator) -> (equals: bool, err: Error) {…}

bool := |a| == |b| Compares the magnitudes only, ignores the sign.

int_from_bytes_big #

Source
int_from_bytes_big :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Read `Int` from a Big Endian binary representation. Sign is detected from the first byte if `signed` is true.

int_from_bytes_big_python #

Source
int_from_bytes_big_python :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Read `Int` from a Big Endian Python binary representation. Sign is detected from the first byte if `signed` is true.

int_from_bytes_little #

Source
int_from_bytes_little :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Read `Int` from a Little Endian binary representation. Sign is detected from the last byte if `signed` is true.

int_from_bytes_little_python #

Source
int_from_bytes_little_python :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Read `Int` from a Little Endian Python binary representation. Sign is detected from the first byte if `signed` is true.

int_gcd #

Source
int_gcd :: proc(res, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

Greatest Common Divisor.

int_gcd_lcm #

Source
int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

Function computing both GCD and (if target isn't `nil`) also LCM.

int_get #

Source
int_get :: proc(a: ^Int, $T: typeid, allocator := context.allocator) -> (res: typeid, err: Error) {…}

TODO: Think about using `count_bits` to check if the value could be returned completely, and maybe return max(T), .Integer_Overflow if not?

int_greater_than #

Source
int_greater_than :: proc(a, b: ^Int, allocator := context.allocator) -> (greater_than: bool, err: Error) {…}

bool := a > b

int_greater_than_abs #

Source
int_greater_than_abs :: proc(a, b: ^Int, allocator := context.allocator) -> (greater_than: bool, err: Error) {…}

bool := |a| > |b| Compares the magnitudes only, ignores the sign.

int_greater_than_digit #

Source
int_greater_than_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (greater_than: bool, err: Error) {…}

bool := a > b

int_greater_than_or_equal #

Source
int_greater_than_or_equal :: proc(a, b: ^Int, allocator := context.allocator) -> (greater_than_or_equal: bool, err: Error) {…}

bool := a >= b

int_greater_than_or_equal_abs #

Source
int_greater_than_or_equal_abs :: proc(a, b: ^Int, allocator := context.allocator) -> (greater_than_or_equal: bool, err: Error) {…}

bool := |a| >= |b| Compares the magnitudes only, ignores the sign.

int_greater_than_or_equal_digit #

Source
int_greater_than_or_equal_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (greater_than_or_equal: bool, err: Error) {…}

bool := a >= b

int_halve #

Source
int_halve :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

dest = src / 2 dest = src >> 1

int_inf #

Source
int_inf :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to Inf and optionally shrink it to the minimum backing size.

int_init_multi #

Source
int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err: Error) {…}

Allocates several `Int`s at once.

int_is_power_of_two #

Source
int_is_power_of_two :: proc(a: ^Int, allocator := context.allocator) -> (res: bool, err: Error) {…}

int_is_square #

Source
int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (square: bool, err: Error) {…}

Check if remainders are possible squares - fast exclude non-squares. Returns `true` if `a` is a square, `false` if not. Assumes `a` not to be `nil` and to have been initialized.

int_itoa_cstring #

Source
int_itoa_cstring :: proc(a: ^Int, radix: i8 = i8(10), allocator := context.allocator) -> (res: cstring, err: Error) {…}

This version of `itoa` allocates on behalf of the caller. The caller must free the string. The radix defaults to 10.

int_itoa_raw #

Source
int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size: int = int(-1), zero_terminate: bool = false) -> (written: int, err: Error) {…}

A low-level `itoa` using a caller-provided buffer. `itoa_string` and `itoa_cstring` use this. You can use also use it if you want to pre-allocate a buffer and optionally reuse it. Use `radix_size` or `radix_size_estimate` to determine a buffer size big enough. You can pass the output of `radix_size` to `size` if you've previously called it to size the output buffer. If you haven't, this routine will call it. This way it knows if the buffer is the appropriate size, and we can write directly in place without a reverse step at the end. === === === IMPORTANT === === === If you determined the buffer size using `radix_size_estimate`, or have a buffer that you reuse that you know is large enough, don't pass this size unless you know what you are doing, because we will always write backwards starting at last byte of the buffer. Keep in mind that if you set `size` yourself and it's smaller than the buffer, it'll result in buffer overflows, as we use it to avoid reversing at the end and having to perform a buffer overflow check each character.

int_itoa_string #

Source
int_itoa_string :: proc(a: ^Int, radix: i8 = i8(10), zero_terminate: bool = false, allocator := context.allocator) -> (res: string, err: Error) {…}

This version of `itoa` allocates on behalf of the caller. The caller must free the string. The radix defaults to 10.

int_lcm #

Source
int_lcm :: proc(res, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

Least Common Multiple.

int_less_than #

Source
int_less_than :: proc(a, b: ^Int, allocator := context.allocator) -> (less_than: bool, err: Error) {…}

bool := a < b

int_less_than_abs #

Source
int_less_than_abs :: proc(a, b: ^Int, allocator := context.allocator) -> (less_than: bool, err: Error) {…}

bool := |a| < |b| Compares the magnitudes only, ignores the sign.

int_less_than_digit #

Source
int_less_than_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (less_than: bool, err: Error) {…}

bool := a < b

int_less_than_or_equal #

Source
int_less_than_or_equal :: proc(a, b: ^Int, allocator := context.allocator) -> (less_than_or_equal: bool, err: Error) {…}

bool := a <= b

int_less_than_or_equal_abs #

Source
int_less_than_or_equal_abs :: proc(a, b: ^Int, allocator := context.allocator) -> (less_than_or_equal: bool, err: Error) {…}

bool := |a| <= |b| Compares the magnitudes only, ignores the sign.

int_less_than_or_equal_digit #

Source
int_less_than_or_equal_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (less_than_or_equal: bool, err: Error) {…}

bool := a <= b

int_minus_inf #

Source
int_minus_inf :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to -Inf and optionally shrink it to the minimum backing size.

int_minus_one #

Source
int_minus_one :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to -1 and optionally shrink it to the minimum backing size.

int_mod #

Source
int_mod :: proc(remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = numerator % denominator. 0 <= remainder < denominator if denominator > 0 denominator < remainder <= 0 if denominator < 0

int_mod_bits #

Source
int_mod_bits :: proc(remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

remainder = numerator % (1 << bits)

int_mul #

Source
int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.allocator) -> (err: Error) {…}

High level multiplication (handles sign).

int_mul_digit #

Source
int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT, allocator := context.allocator) -> (err: Error) {…}

Multiply by a DIGIT.

int_mulmod #

Source
int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number * multiplicand) % modulus.

int_nan #

Source
int_nan :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to NaN and optionally shrink it to the minimum backing size.

int_neg #

Source
int_neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

Set `dest` to `-src`.

int_one #

Source
int_one :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to 1 and optionally shrink it to the minimum backing size.

int_pow #

Source
int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allocator) -> (err: Error) {…}

Calculate `dest = base^power` using a square-multiply algorithm.

int_pow_int #

Source
int_pow_int :: proc(dest: ^Int, base, power: int, allocator := context.allocator) -> (err: Error) {…}

Calculate `dest = base^power` using a square-multiply algorithm.

int_root_n #

Source
int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.allocator) -> (err: Error) {…}

Find the nth root of an Integer. Result found such that `(dest)**n <= src` and `(dest+1)**n > src` This algorithm uses Newton's approximation `x[i+1] = x[i] - f(x[i])/f'(x[i])`, which will find the root in `log(n)` time where each step involves a fair bit.

int_set_from_integer #

Source
int_set_from_integer :: proc(dest: ^Int, src: $T, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Helpers to set an `Int` to a specific value.

int_shl #

Source
int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

Shift left by a certain bit count.

int_shr_signed #

Source
int_shr_signed :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

Shift right by a certain bit count with sign extension.

int_shrmod #

Source
int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

quotient, remainder := numerator >> bits; `remainder` is allowed to be passed a `nil`, in which case `mod` won't be computed.

int_sqrmod #

Source
int_sqrmod :: proc(remainder, number, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number * number) % modulus.

int_sqrt #

Source
int_sqrt :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

This function is less generic than `root_n`, simpler and faster.

int_sub #

Source
int_sub :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {…}

High-level subtraction, dest = number - decrease. Handles signs.

int_sub_digit #

Source
int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {…}

Adds the unsigned `DIGIT` immediate to an `Int`, such that the `DIGIT` doesn't have to be turned into an `Int` first. dest = a - digit;

int_submod #

Source
int_submod :: proc(remainder, number, decrease, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number - decrease) % modulus.

int_swap #

Source
int_swap :: proc(a, b: ^Int) {…}

In normal code, you can also write `a, b = b, a`. However, that only swaps within the current scope. This helper swaps completely.

int_to_bytes_big #

Source
int_to_bytes_big :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Return Big Endian binary representation of `a`, either signed or unsigned. If `a` is negative and we ask for the default unsigned representation, we return abs(a).

int_to_bytes_big_python #

Source
int_to_bytes_big_python :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Return Python 3.x compatible Big Endian binary representation of `a`, either signed or unsigned. If `a` is negative when asking for an unsigned number, we return an error like Python does.

int_to_bytes_little #

Source
int_to_bytes_little :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Return Little Endian binary representation of `a`, either signed or unsigned. If `a` is negative and we ask for the default unsigned representation, we return abs(a).

int_to_bytes_little_python #

Source
int_to_bytes_little_python :: proc(a: ^Int, buf: []u8, signed: bool = false, allocator := context.allocator) -> (err: Error) {…}

Return Python 3.x compatible Little Endian binary representation of `a`, either signed or unsigned. If `a` is negative when asking for an unsigned number, we return an error like Python does.

int_to_bytes_size #

Source
int_to_bytes_size :: proc(a: ^Int, signed: bool = false, allocator := context.allocator) -> (size_in_bytes: int, err: Error) {…}

Size binary representation

int_to_cstring #

Source
int_to_cstring :: proc(a: ^Int, radix: i8 = i8(10), allocator := context.allocator) -> (res: cstring, err: Error) {…}

This version of `itoa` allocates on behalf of the caller. The caller must free the string. The radix defaults to 10.

int_to_string #

Source
int_to_string :: proc(a: ^Int, radix: i8 = i8(10), zero_terminate: bool = false, allocator := context.allocator) -> (res: string, err: Error) {…}

This version of `itoa` allocates on behalf of the caller. The caller must free the string. The radix defaults to 10.

internal_assert_initialized #

Source
internal_assert_initialized :: proc(a: ^Int, loc := #caller_location) {…}

Internal helpers.

internal_clamp #

Source
internal_clamp :: proc(a: ^Int) -> (err: Error) {…}

Trim unused digits. This is used to ensure that leading zero digits are trimmed and the leading "used" digit will be non-zero. Typically very fast. Also fixes the sign if there are no more leading digits.

internal_clear_if_uninitialized_multi #

Source
internal_clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocator) -> (err: Error) {…}

internal_clear_if_uninitialized_single #

Source
internal_clear_if_uninitialized_single :: proc(arg: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_count_bits #

Source
internal_count_bits :: proc(a: ^Int) -> (count: int) {…}

Count bits in an `Int`. Assumes `a` not to be `nil` and to have been initialized.

internal_error_if_immutable_multi #

Source
internal_error_if_immutable_multi :: proc "contextless" (args: ..^Int) -> (err: Error) {…}

internal_error_if_immutable_single #

Source
internal_error_if_immutable_single :: proc "contextless" (arg: ^Int) -> (err: Error) {…}

internal_int_abs #

Source
internal_int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

Set `dest` to |`src`|.

internal_int_add_digit #

Source
internal_int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {…}

Low-level addition Int+DIGIT, signed. Handbook of Applied Cryptography, algorithm 14.7. Assumptions: `dest` and `a` != `nil` and have been initalized. `dest` is large enough (a.used + 1) to fit result.

internal_int_add_signed #

Source
internal_int_add_signed :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

Low-level addition, signed. Handbook of Applied Cryptography, algorithm 14.7. Assumptions: `dest`, `a` and `b` != `nil` and have been initalized.

internal_int_add_unsigned #

Source
internal_int_add_unsigned :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

Low-level addition, unsigned. Handbook of Applied Cryptography, algorithm 14.7. Assumptions: `dest`, `a` and `b` != `nil` and have been initalized.

internal_int_addmod #

Source
internal_int_addmod :: proc(remainder, number, addend, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number + addend) % modulus.

internal_int_allocated_cap #

Source
internal_int_allocated_cap :: proc(a: ^Int) -> (cap: int) {…}

This procedure returns the allocated capacity of an Int. Assumes `a` not to be `nil`.

internal_int_and #

Source
internal_int_and :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

2's complement `and`, returns `dest = a & b;`

internal_int_bitfield_extract_bool #

Source
internal_int_bitfield_extract_bool :: proc(a: ^Int, offset: int) -> (val: bool, err: Error) {…}

Helpers to extract values from the `Int`. Offset is zero indexed.

internal_int_bitfield_set_single #

Source
internal_int_bitfield_set_single :: proc(a: ^Int, offset: int) -> (err: Error) {…}

Helpers to (un)set a bit in an Int. Offset is zero indexed.

internal_int_bitfield_toggle_single #

Source
internal_int_bitfield_toggle_single :: proc(a: ^Int, offset: int) -> (err: Error) {…}

internal_int_bitfield_unset_single #

Source
internal_int_bitfield_unset_single :: proc(a: ^Int, offset: int) -> (err: Error) {…}

internal_int_clear #

Source
internal_int_clear :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Clear `Int` and resize it to the default size. Assumes `a` not to be `nil`.

internal_int_compare #

Source
internal_int_compare :: proc(a, b: ^Int) -> (comparison: int) {…}

Compare two `Int`s, signed. Returns -1 if `a` < `b`, 0 if `a` == `b` and 1 if `b` > `a`. Expects `a` and `b` both to be valid `Int`s, i.e. initialized and not `nil`.

internal_int_compare_digit #

Source
internal_int_compare_digit :: proc(a: ^Int, b: DIGIT) -> (comparison: int) {…}

Compare an `Int` to an unsigned number upto `DIGIT & _MASK`. Returns -1 if `a` < `b`, 0 if `a` == `b` and 1 if `b` > `a`. Expects: `a` and `b` both to be valid `Int`s, i.e. initialized and not `nil`.

internal_int_compare_magnitude #

Source
internal_int_compare_magnitude :: proc(a, b: ^Int) -> (comparison: int) {…}

Compare the magnitude of two `Int`s, unsigned.

internal_int_complement #

Source
internal_int_complement :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

dest = ~src

internal_int_copy #

Source
internal_int_copy :: proc(dest, src: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Copy one `Int` to another.

internal_int_count_lsb #

Source
internal_int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {…}

Returns the number of trailing zeroes before the first one. Differs from regular `ctz` in that 0 returns 0. Assumes `a` not to be `nil` and have been initialized.

internal_int_decr #

Source
internal_int_decr :: proc(dest: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_int_destroy #

Source
internal_int_destroy :: proc(integers: ..^Int) {…}

Deallocates the backing memory of one or more `Int`s. Asssumes none of the `integers` to be a `nil`.

internal_int_div #

Source
internal_int_div :: proc(quotient, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {…}

Asssumes quotient, numerator and denominator to have been initialized and not to be nil.

internal_int_divmod #

Source
internal_int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {…}

divmod. Both the quotient and remainder are optional and may be passed a nil. `numerator` and `denominator` are expected not to be `nil` and have been initialized.

internal_int_divmod_digit #

Source
internal_int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {…}

Single digit division (based on routine from MPI). The quotient is optional and may be passed a nil.

internal_int_equals #

Source
internal_int_equals :: proc(a, b: ^Int) -> (equals: bool) {…}

bool := a == b

internal_int_equals_abs #

Source
internal_int_equals_abs :: proc(a, b: ^Int) -> (equals: bool) {…}

bool := |a| == |b| Compares the magnitudes only, ignores the sign.

internal_int_exponent_mod #

Source
internal_int_exponent_mod :: proc(res, G, X, P: ^Int, allocator := context.allocator) -> (err: Error) {…}

This is a shell function that calls either the normal or Montgomery exptmod functions. Originally the call to the Montgomery code was embedded in the normal function but that wasted alot of stack space for nothing (since 99% of the time the Montgomery code would be called). Computes res == G**X mod P. Assumes `res`, `G`, `X` and `P` to not be `nil` and for `G`, `X` and `P` to have been initialized.

internal_int_extended_euclidean #

Source
internal_int_extended_euclidean :: proc(
	a, b, U1, U2, U3: ^Int, 
	allocator := context.allocator, 
) -> (err: Error) {…}

Extended Euclidean algorithm of (a, b) produces `a * u1` + `b * u2` = `u3`.

internal_int_factorial #

Source
internal_int_factorial :: proc(res: ^Int, n: int, allocator := context.allocator) -> (err: Error) {…}

TODO: Use Sterling's Approximation to estimate log2(N!) to size the result. This way we'll have to reallocate less, possibly not at all.

internal_int_gcd #

Source
internal_int_gcd :: proc(res_gcd, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_int_gcd_lcm #

Source
internal_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

Returns GCD, LCM or both. Assumes `a` and `b` to have been initialized. `res_gcd` and `res_lcm` can be nil or ^Int depending on which results are desired.

internal_int_get #

Source
internal_int_get :: proc(a: ^Int, $T: typeid) -> (res: typeid, err: Error) {…}

TODO: Think about using `count_bits` to check if the value could be returned completely, and maybe return max(T), .Integer_Overflow if not?

internal_int_greater_than #

Source
internal_int_greater_than :: proc(a, b: ^Int) -> (greater_than: bool) {…}

bool := a > b

internal_int_greater_than_abs #

Source
internal_int_greater_than_abs :: proc(a, b: ^Int) -> (greater_than: bool) {…}

bool := |a| > |b| Compares the magnitudes only, ignores the sign.

internal_int_greater_than_digit #

Source
internal_int_greater_than_digit :: proc(a: ^Int, b: DIGIT) -> (greater_than: bool) {…}

bool := a > b

internal_int_greater_than_or_equal #

Source
internal_int_greater_than_or_equal :: proc(a, b: ^Int) -> (greater_than_or_equal: bool) {…}

bool := a >= b

internal_int_greater_than_or_equal_abs #

Source
internal_int_greater_than_or_equal_abs :: proc(a, b: ^Int) -> (greater_than_or_equal: bool) {…}

bool := |a| >= |b| Compares the magnitudes only, ignores the sign.

internal_int_greater_than_or_equal_digit #

Source
internal_int_greater_than_or_equal_digit :: proc(a: ^Int, b: DIGIT) -> (greater_than_or_equal: bool) {…}

bool := a >= b

internal_int_grow #

Source
internal_int_grow :: proc(a: ^Int, digits: int, allow_shrink: bool = false, allocator := context.allocator) -> (err: Error) {…}

internal_int_incr #

Source
internal_int_incr :: proc(dest: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_int_inf #

Source
internal_int_inf :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to Inf and optionally shrink it to the minimum backing size.

internal_int_init_multi #

Source
internal_int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err: Error) {…}

Allocates several `Int`s at once.

internal_int_inverse_modulo #

Source
internal_int_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

hac 14.61, pp608.

internal_int_invmod #

Source
internal_int_invmod :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

hac 14.61, pp608.

internal_int_is_even #

Source
internal_int_is_even :: proc(a: ^Int) -> (even: bool) {…}

This procedure will return `true` if the `Int` is even, `false` if not. Assumes `a` not to be `nil`.

internal_int_is_initialized #

Source
internal_int_is_initialized :: proc(a: ^Int) -> (initialized: bool) {…}

This procedure will return `true` if the `Int` is initialized, `false` if not. Assumes `a` not to be `nil`.

internal_int_is_negative #

Source
internal_int_is_negative :: proc(a: ^Int) -> (negative: bool) {…}

This procedure will return `true` if the `Int` is negative, `false` if not. Assumes `a` not to be `nil`.

internal_int_is_odd #

Source
internal_int_is_odd :: proc(a: ^Int) -> (odd: bool) {…}

This procedure will return `true` if the `Int` is even, `false` if not. Assumes `a` not to be `nil`.

internal_int_is_positive #

Source
internal_int_is_positive :: proc(a: ^Int) -> (positive: bool) {…}

This procedure will return `true` if the `Int` is positive, `false` if not. Assumes `a` not to be `nil`.

internal_int_is_power_of_two #

Source
internal_int_is_power_of_two :: proc(a: ^Int) -> (power_of_two: bool) {…}

This procedure will return `true` if the `Int` is a power of two, `false` if not. Assumes `a` not to be `nil`.

internal_int_is_prime #

Source
internal_int_is_prime :: proc(a: ^Int, miller_rabin_trials: int = int(-1), miller_rabin_only: bool = USE_MILLER_RABIN_ONLY, allocator := context.allocator) -> (is_prime: bool, err: Error) {…}

`a` is the big Int to test for primality. `miller_rabin_trials` can be one of the following: `< 0`: For `a` up to 3_317_044_064_679_887_385_961_981, set `miller_rabin_trials` to negative to run a predetermined number of trials for a deterministic answer. `= 0`: Run Miller-Rabin with bases 2, 3 and one random base < `a`. Non-deterministic. `> 0`: Run Miller-Rabin with bases 2, 3 and `miller_rabin_trials` number of random bases. Non-deterministic. `miller_rabin_only`: `false` Also use either Frobenius-Underwood or Lucas-Selfridge, depending on the compile-time `MATH_BIG_USE_FROBENIUS_TEST` choice. `true` Run Rabin-Miller trials but skip Frobenius-Underwood / Lucas-Selfridge. `r` takes a pointer to an instance of `core:math/rand`'s `Rand` and may be `nil` to use the global one. Returns `is_prime` (bool), where: `false` Definitively composite. `true` Probably prime if `miller_rabin_trials` >= 0, with increasing certainty with more trials. Deterministically prime if `miller_rabin_trials` = 0 for `a` up to 3_317_044_064_679_887_385_961_981. Assumes `a` not to be `nil` and to have been initialized.

internal_int_is_square #

Source
internal_int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (square: bool, err: Error) {…}

Check if remainders are possible squares - fast exclude non-squares. Returns `true` if `a` is a square, `false` if not. Assumes `a` not to be `nil` and to have been initialized.

internal_int_is_zero #

Source
internal_int_is_zero :: proc(a: ^Int) -> (zero: bool) {…}

This procedure will return `true` if the `Int` is zero, `false` if not. Assumes `a` not to be `nil`.

internal_int_kronecker #

Source
internal_int_kronecker :: proc(a, p: ^Int, allocator := context.allocator) -> (kronecker: int, err: Error) {…}

Kronecker/Legendre symbol (a|p) Straightforward implementation of algorithm 1.4.10 in Henri Cohen: "A Course in Computational Algebraic Number Theory" @book{cohen2013course, title={A course in computational algebraic number theory}, author={Cohen, Henri}, volume={138}, year={2013}, publisher={Springer Science \& Business Media} } Assumes `a` and `p` to not be `nil` and to have been initialized.

internal_int_lcm #

Source
internal_int_lcm :: proc(res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_int_legendre #

Source
internal_int_legendre :: proc(a, p: ^Int, allocator := context.allocator) -> (kronecker: int, err: Error) {…}

Kronecker/Legendre symbol (a|p) Straightforward implementation of algorithm 1.4.10 in Henri Cohen: "A Course in Computational Algebraic Number Theory" @book{cohen2013course, title={A course in computational algebraic number theory}, author={Cohen, Henri}, volume={138}, year={2013}, publisher={Springer Science \& Business Media} } Assumes `a` and `p` to not be `nil` and to have been initialized.

internal_int_less_than #

Source
internal_int_less_than :: proc(a, b: ^Int) -> (less_than: bool) {…}

bool := a < b

internal_int_less_than_abs #

Source
internal_int_less_than_abs :: proc(a, b: ^Int) -> (less_than: bool) {…}

bool := |a| < |b| Compares the magnitudes only, ignores the sign.

internal_int_less_than_digit #

Source
internal_int_less_than_digit :: proc(a: ^Int, b: DIGIT) -> (less_than: bool) {…}

bool := a < b

internal_int_less_than_or_equal #

Source
internal_int_less_than_or_equal :: proc(a, b: ^Int) -> (less_than_or_equal: bool) {…}

bool := a <= b

internal_int_less_than_or_equal_abs #

Source
internal_int_less_than_or_equal_abs :: proc(a, b: ^Int) -> (less_than_or_equal: bool) {…}

bool := |a| <= |b| Compares the magnitudes only, ignores the sign.

internal_int_less_than_or_equal_digit #

Source
internal_int_less_than_or_equal_digit :: proc(a: ^Int, b: DIGIT) -> (less_than_or_equal: bool) {…}

bool := a <= b

internal_int_log #

Source
internal_int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {…}

Returns log_base(a). Assumes `a` to not be `nil` and have been iniialized.

internal_int_minus_inf #

Source
internal_int_minus_inf :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to -Inf and optionally shrink it to the minimum backing size.

internal_int_minus_one #

Source
internal_int_minus_one :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to -1 and optionally shrink it to the minimum backing size.

internal_int_mod #

Source
internal_int_mod :: proc(remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = numerator % denominator. 0 <= remainder < denominator if denominator > 0 denominator < remainder <= 0 if denominator < 0 Asssumes quotient, numerator and denominator to have been initialized and not to be nil.

internal_int_mod_bits #

Source
internal_int_mod_bits :: proc(remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

remainder = numerator % (1 << bits) Assumes `remainder` and `numerator` both not to be `nil` and `bits` to be >= 0.

internal_int_mod_digit #

Source
internal_int_mod_digit :: proc(numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {…}

internal_int_mul #

Source
internal_int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.allocator) -> (err: Error) {…}

High level multiplication (handles sign).

internal_int_mul_denom #

Source
internal_int_mul_denom :: proc(dst, x, y: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_int_mul_digit #

Source
internal_int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT, allocator := context.allocator) -> (err: Error) {…}

Multiply by a DIGIT.

internal_int_mul_integer #

Source
internal_int_mul_integer :: proc(dest, a: ^Int, b: $T, allocator := context.allocator) -> (err: Error) {…}

Multiply bigint `a` with int `d` and put the result in `dest`. Like `internal_int_mul_digit` but with an integer as the small input.

internal_int_mulmod #

Source
internal_int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number * multiplicand) % modulus.

internal_int_nan #

Source
internal_int_nan :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to NaN and optionally shrink it to the minimum backing size.

internal_int_neg #

Source
internal_int_neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

Set `dest` to `-src`.

internal_int_one #

Source
internal_int_one :: proc(a: ^Int, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Set the `Int` to 1 and optionally shrink it to the minimum backing size.

internal_int_or #

Source
internal_int_or :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

2's complement `or`, returns `dest = a | b;`

internal_int_pack #

Source
internal_int_pack :: proc(a: ^Int, buf: []$T, nails: int = 0, order: Order = Order.LSB_First) -> (written: int, err: Error) {…}

Based on gmp's mpz_export. See https://gmplib.org/manual/Integer-Import-and-Export.html `buf` is a pre-allocated slice of type `T` "words", which must be an unsigned integer of some description. Use `internal_int_pack_count(a, T, nails)` to calculate the necessary size. The library internally uses `DIGIT` as the type, which is u64 or u32 depending on the platform. You are of course welcome to export to []u8, []u32be, and so forth. After this you can use `mem.slice_data_cast` to interpret the buffer as bytes if you so choose. `nails` are the number of top bits the output "word" reserves. To mimic the internals of this library, this would be 4. To use the minimum amount of output bytes, set `nails` to 0 and pass a `[]u8`. IMPORTANT: `pack` serializes the magnitude of an Int, that is, the output is unsigned. Assumes `a` not to be `nil` and to have been initialized.

internal_int_pack_count #

Source
internal_int_pack_count :: proc(a: ^Int, $T: typeid, nails: int = 0) -> (size_needed: int) {…}

Calculate the size needed for `internal_int_pack`. See https://gmplib.org/manual/Integer-Import-and-Export.html

internal_int_pow #

Source
internal_int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allocator) -> (err: Error) {…}

Calculate dest = base^power using a square-multiply algorithm. Assumes `dest` and `base` not to be `nil` and to have been initialized.

internal_int_pow_int #

Source
internal_int_pow_int :: proc(dest: ^Int, base, power: int, allocator := context.allocator) -> (err: Error) {…}

Calculate `dest = base^power`. Assumes `dest` not to be `nil` and to have been initialized.

internal_int_power_modulo #

Source
internal_int_power_modulo :: proc(res, G, X, P: ^Int, allocator := context.allocator) -> (err: Error) {…}

This is a shell function that calls either the normal or Montgomery exptmod functions. Originally the call to the Montgomery code was embedded in the normal function but that wasted alot of stack space for nothing (since 99% of the time the Montgomery code would be called). Computes res == G**X mod P. Assumes `res`, `G`, `X` and `P` to not be `nil` and for `G`, `X` and `P` to have been initialized.

internal_int_power_of_two #

Source
internal_int_power_of_two :: proc(a: ^Int, power: int, allocator := context.allocator) -> (err: Error) {…}

internal_int_powmod #

Source
internal_int_powmod :: proc(res, G, X, P: ^Int, allocator := context.allocator) -> (err: Error) {…}

This is a shell function that calls either the normal or Montgomery exptmod functions. Originally the call to the Montgomery code was embedded in the normal function but that wasted alot of stack space for nothing (since 99% of the time the Montgomery code would be called). Computes res == G**X mod P. Assumes `res`, `G`, `X` and `P` to not be `nil` and for `G`, `X` and `P` to have been initialized.

internal_int_prime_frobenius_underwood #

Source
internal_int_prime_frobenius_underwood :: proc(N: ^Int, allocator := context.allocator) -> (result: bool, err: Error) {…}

internal_int_prime_is_divisible #

Source
internal_int_prime_is_divisible :: proc(a: ^Int, allocator := context.allocator) -> (res: bool, err: Error) {…}

Determines if an Integer is divisible by one of the _PRIME_TABLE primes. Returns true if it is, false if not.

internal_int_prime_miller_rabin #

Source
internal_int_prime_miller_rabin :: proc(a, b: ^Int, allocator := context.allocator) -> (probably_prime: bool, err: Error) {…}

Miller-Rabin test of "a" to the base of "b" as described in HAC pp. 139 Algorithm 4.24. Sets result to `false` if definitely composite or `true` if probably prime. Randomly the chance of error is no more than 1/4 and often very much lower. Assumes `a` and `b` not to be `nil` and to have been initialized.

internal_int_prime_next_prime #

Source
internal_int_prime_next_prime :: proc(a: ^Int, trials: int, bbs_style: bool, allocator := context.allocator) -> (err: Error) {…}

Finds the next prime after the number `a` using `t` trials of Miller-Rabin, in place: It sets `a` to the prime found. `bbs_style` = true means the prime must be congruent to 3 mod 4

internal_int_prime_strong_lucas_selfridge #

Source
internal_int_prime_strong_lucas_selfridge :: proc(a: ^Int, allocator := context.allocator) -> (lucas_selfridge: bool, err: Error) {…}

Strong Lucas-Selfridge test. returns true if it is a strong L-S prime, false if it is composite Code ported from Thomas Ray Nicely's implementation of the BPSW test at http://www.trnicely.net/misc/bpsw.html Freeware copyright (C) 2016 Thomas R. Nicely <http://www.trnicely.net>. Released into the public domain by the author, who disclaims any legal liability arising from its use. The multi-line comments are made by Thomas R. Nicely and are copied verbatim. (If that name sounds familiar, he is the guy who found the fdiv bug in the Pentium CPU.)

internal_int_random #

Source
internal_int_random :: proc(dest: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

internal_int_read_from_ascii_file #

Source
internal_int_read_from_ascii_file :: proc(a: ^Int, filename: string, radix: i8 = i8(10), allocator := context.allocator) -> (err: Error) {…}

Read an Int from an ASCII file.

internal_int_root_n #

Source
internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.allocator) -> (err: Error) {…}

Find the nth root of an Integer. Result found such that `(dest)**n <= src` and `(dest+1)**n > src` This algorithm uses Newton's approximation `x[i+1] = x[i] - f(x[i])/f'(x[i])`, which will find the root in `log(n)` time where each step involves a fair bit. Assumes `dest` and `src` not to be `nil` and have been initialized.

internal_int_scale_denom #

Source
internal_int_scale_denom :: proc(dst, x, y: ^Int, allocator := context.allocator) -> (err: Error) {…}

internal_int_set_from_integer #

Source
internal_int_set_from_integer :: proc(dest: ^Int, src: $T, minimize: bool = false, allocator := context.allocator) -> (err: Error) {…}

Helpers to set an `Int` to a specific value.

internal_int_shl #

Source
internal_int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

Shift left by a certain bit count.

internal_int_shl1 #

Source
internal_int_shl1 :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

dest = src * 2 dest = src << 1

internal_int_shr #

Source
internal_int_shr :: proc(dest, source: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

internal_int_shr_signed #

Source
internal_int_shr_signed :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

Shift right by a certain bit count with sign extension.

internal_int_shr1 #

Source
internal_int_shr1 :: proc(dest, src: ^Int) -> (err: Error) {…}

dest = src / 2 dest = src >> 1 Assumes `dest` and `src` not to be `nil` and have been initialized. We make no allocations here.

internal_int_shrink #

Source
internal_int_shrink :: proc(a: ^Int) -> (err: Error) {…}

Resize backing store. We don't need to pass the allocator, because the storage itself stores it. Assumes `a` not to be `nil`, and to have already been initialized.

internal_int_shrmod #

Source
internal_int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {…}

quotient, remainder := numerator >> bits; `remainder` is allowed to be passed a `nil`, in which case `mod` won't be computed.

internal_int_sqrmod #

Source
internal_int_sqrmod :: proc(remainder, number, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number * number) % modulus.

internal_int_sqrt #

Source
internal_int_sqrt :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {…}

This function is less generic than `root_n`, simpler and faster. Assumes `dest` and `src` not to be `nil` and to have been initialized.

internal_int_sqrtmod_prime #

Source
internal_int_sqrtmod_prime :: proc(res, n, prime: ^Int, allocator := context.allocator) -> (err: Error) {…}

Tonelli-Shanks algorithm https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm https://gmplib.org/list-archives/gmp-discuss/2013-April/005300.html

internal_int_sub_digit #

Source
internal_int_sub_digit :: proc(dest, number: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {…}

Low-level subtraction, signed. Handbook of Applied Cryptography, algorithm 14.9. dest = number - decrease. Assumes |number| > |decrease|. Assumptions: `dest`, `number` != `nil` and have been initalized. `dest` is large enough (number.used + 1) to fit result.

internal_int_sub_signed #

Source
internal_int_sub_signed :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {…}

Low-level subtraction, signed. Handbook of Applied Cryptography, algorithm 14.9. dest = number - decrease. Assumes |number| > |decrease|. Assumptions: `dest`, `number` and `decrease` != `nil` and have been initalized.

internal_int_sub_unsigned #

Source
internal_int_sub_unsigned :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {…}

Low-level subtraction, dest = number - decrease. Assumes |number| > |decrease|. Handbook of Applied Cryptography, algorithm 14.9. Assumptions: `dest`, `number` and `decrease` != `nil` and have been initalized.

internal_int_submod #

Source
internal_int_submod :: proc(remainder, number, decrease, modulus: ^Int, allocator := context.allocator) -> (err: Error) {…}

remainder = (number - decrease) % modulus.

internal_int_swap #

Source
internal_int_swap :: proc(a, b: ^Int) {…}

In normal code, you can also write `a, b = b, a`. However, that only swaps within the current scope. This helper swaps completely.

internal_int_unpack #

Source
internal_int_unpack :: proc(a: ^Int, buf: []$T, nails: int = 0, order: Order = Order.LSB_First, allocator := context.allocator) -> (err: Error) {…}

internal_int_write_to_ascii_file #

Source
internal_int_write_to_ascii_file :: proc(a: ^Int, filename: string, radix: i8 = i8(10), allocator := context.allocator) -> (err: Error) {…}

Write an Int to an ASCII file.

internal_int_xor #

Source
internal_int_xor :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

2's complement `xor`, returns `dest = a ~ b;`

internal_int_zero_unused #

Source
internal_int_zero_unused :: proc(dest: ^Int, old_used: int = -1) {…}

internal_platform_abs #

Source
internal_platform_abs :: proc(n: $T) -> $$deferred_return {…}

internal_platform_count_lsb #

Source
internal_platform_count_lsb :: proc(a: $T) -> (count: int) {…}

internal_prime_fermat #

Source
internal_prime_fermat :: proc(a, b: ^Int, allocator := context.allocator) -> (fermat: bool, err: Error) {…}

Performs one Fermat test. If "a" were prime then b**a == b (mod a) since the order of the multiplicative sub-group would be phi(a) = a-1. That means it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). Returns `true` if the congruence holds, or `false` otherwise. Assumes `a` and `b` not to be `nil` and to have been initialized.

internal_random_prime #

Source
internal_random_prime :: proc(a: ^Int, size_in_bits: int, trials: int, flags: bit_set[Primality_Flag] = Primality_Flags{}, allocator := context.allocator) -> (err: Error) {…}

Makes a truly random prime of a given size (bits), Flags are as follows: Blum_Blum_Shub - Make prime congruent to 3 mod 4 Safe - Make sure (p-1)/2 is prime as well (implies .Blum_Blum_Shub) Second_MSB_On - Make the 2nd highest bit one This is possibly the mother of all prime generation functions, muahahahahaha!

internal_rat_norm #

Source
internal_rat_norm :: proc(z: ^Rat, allocator := context.allocator) -> (err: Error) {…}

internal_sqr #

Source
internal_sqr :: proc(dest, src: ^Int, allocator := context.allocator) -> (res: Error) {…}

number_of_rabin_miller_trials #

Source
number_of_rabin_miller_trials :: proc(bit_size: int) -> (number_of_trials: int) {…}

Returns the number of Rabin-Miller trials needed for a given bit size.

permutations_with_repetition #

Source
permutations_with_repetition :: proc(dest: ^Int, base, power: int, allocator := context.allocator) -> (err: Error) {…}

Calculate `dest = base^power` using a square-multiply algorithm.

permutations_without_repetition #

Source
permutations_without_repetition :: proc(dest: ^Int, n, r: int) -> (error: Error) {…}

With `n` items, calculate how many ways that `r` of them can be ordered without any repeats.

platform_abs #

Source
platform_abs :: proc(n: $T) -> $$deferred_return {…}

radix_size #

Source
radix_size :: proc(a: ^Int, radix: i8, zero_terminate: bool = false, allocator := context.allocator) -> (size: int, err: Error) {…}

We size for `string` by default.

rat_add_rat #

Source
rat_add_rat :: proc(dst, x, y: ^Rat, allocator := context.allocator) -> (err: Error) {…}

rat_compare #

Source
rat_compare :: proc(x, y: ^Rat, allocator := context.allocator) -> (comparison: int, error: Error) {…}

rat_div_rat #

Source
rat_div_rat :: proc(dst, x, y: ^Rat, allocator := context.allocator) -> (err: Error) {…}

rat_mul_rat #

Source
rat_mul_rat :: proc(dst, x, y: ^Rat, allocator := context.allocator) -> (err: Error) {…}

rat_set_frac_int #

Source
rat_set_frac_int :: proc(dst: ^Rat, a, b: ^Int, allocator := context.allocator) -> (err: Error) {…}

rat_sub_rat #

Source
rat_sub_rat :: proc(dst, x, y: ^Rat, allocator := context.allocator) -> (err: Error) {…}

shrink #

Source
shrink :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {…}

Resize backing store.

string_to_int #

Source
string_to_int :: proc(res: ^Int, input: string, radix: i8 = i8(10), allocator := context.allocator) -> (err: Error) {…}

Read a string [ASCII] in a given radix.

Procedure Groups

188

Variables

19

FACTORIAL_BINARY_SPLIT_CUTOFF #

Source
FACTORIAL_BINARY_SPLIT_CUTOFF: int = 6100

Cutoff to switch to int_factorial_binary_split, and its max recursion level.

FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS #

Source
FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS: int = 100

FACTORIAL_MAX_N #

Source
FACTORIAL_MAX_N: int = 1_000_000

Largest `N` for which we'll compute `N!`

MAX_ITERATIONS_RANDOM_PRIME #

Source
MAX_ITERATIONS_RANDOM_PRIME: int = 1_000_000

How many times we'll call `internal_int_random` during random prime generation before we bail out. Set to 0 or less to try indefinitely.

MUL_KARATSUBA_CUTOFF #

Source
MUL_KARATSUBA_CUTOFF: int = _DEFAULT_MUL_KARATSUBA_CUTOFF

RADIX_TABLE #

Source
RADIX_TABLE: string = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"

Characters used in radix conversions.

RADIX_TABLE_REVERSE #

Source
@(rodata)
RADIX_TABLE_REVERSE: [80]u8 = [RADIX_TABLE_REVERSE_SIZE]u8{0x3e, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d}

RANDOM_PRIME_ITERATIONS_USED #

Source
@(thread_local)
RANDOM_PRIME_ITERATIONS_USED: int

How many iterations we used for the last random prime.

SQR_KARATSUBA_CUTOFF #

Source
SQR_KARATSUBA_CUTOFF: int = _DEFAULT_SQR_KARATSUBA_CUTOFF

USE_MILLER_RABIN_ONLY #

Source
USE_MILLER_RABIN_ONLY: bool = false

Runtime tunable to use Miller-Rabin primality testing only and skip the above.