intn.h
Include dependency graph for intn.h:
This graph shows which files directly or indirectly include intn.h:
Multi-precision integer arithmetic for up to 256-bit integers (IntN)
The module name “intn” stands for “Integer N-bits” where N can be up to 256 in the current implementation. While these are often called “big integers” (bigints) in higher-level contexts, we use the term “multi-precision integer” in this header to emphasize the implementation using arrays of fixed-precision digits.
This module provides multi-precision integer arithmetic operations on arrays of digits (also called limbs in other libraries). Integers are represented in sign-magnitude form (not two’s complement) with the sign stored separately. The magnitude is the absolute value of the integer, stored as an array of unsigned digits.
Integer Representation
Multi-precision integers are stored as arrays of intn_digit_t digits in little-endian digit order (least significant digit first):
digit[0] contains the least significant bits
digit[n-1] contains the most significant bits
Example representations:
// 0xCAFEFACEDEADBEEF parsed from hex string:
// bigint[0] = 0xDEADBEEF, bigint[1] = 0xCAFEFACE, sign = IntNPositiveInteger
// -0xCAFEFACEDEADBEEF1234:
// {0xBEEF1234, 0xFACEDEAD, 0xCAFE}, sign = IntNNegativeInteger
// 2^127 (0x80000000000000000000000000000000):
// {0x0, 0x0, 0x0, 0x80000000}, sign = IntNPositiveInteger
Normalized (Canonical) Form
An integer is in normalized form when it has no leading zero digits. Leading zeros are zero-valued digits at the end of the array (highest indices).
Examples:
// Normalized form (no leading zeros):
// {0xDEADBEEF, 0xCAFEFACE} - 2 digits, both non-zero
// Not normalized (has leading zero):
// {0xDEADBEEF, 0xCAFEFACE, 0x0} - digit[2] is a leading zero
// Function example:
intn_count_digits({0x0, 0x0, 0x0, 0x80000000}, 4) -> 4 (normalized)
intn_count_digits({0x0, 0x0, 0x0, 0x80000000, 0x0}, 5) -> 4 (not normalized)
Functions Requiring Normalized Input
The following functions MUST receive normalized input for correct operation:
intn_to_int64()- for correct conversionintn_fits_int64()- for accurate check
All other functions accept both normalized and non-normalized inputs.
Output Buffer Sizing
Functions require pre-allocated output buffers. Use the provided macros (e.g., INTN_MUL_OUT_LEN) to ensure sufficient space. No output length parameter is passed - callers must ensure buffers are large enough.
Note
On little-endian systems, the memory layout matches native uint64_t for 2-digit values. On big-endian systems, digit order remains the same but byte order within each digit follows system endianness.
Warning
Multi-precision integers cannot be compared using memcmp
Note
Algorithms for multiplication and division are based on Hacker’s Delight
Note
We use the term “digit” instead of “limb” in this module
Defines
-
INTN_INT64_LEN 2
Number of
intn_digit_tdigits needed to represent anyint64_tvalue.
-
INTN_UINT64_LEN 2
Number of
intn_digit_tdigits needed to represent anyuint64_tvalue.
-
INTN_MAX_IN_LEN 8
Maximum input length in digits (256 bits / 32 bits = 8 digits)
-
INTN_MAX_RES_LEN (INTN_MAX_IN_LEN + INTN_INT64_LEN + 1)
Maximum result length in digits, provides extra room for intermediate overflow.
Note
Larger than
INTN_MAX_IN_LENto accommodate temporary overflow before normalization
-
INTN_BSL_MAX_RES_LEN 8
Maximum result length for bit shift left operations.
-
MAX_LEN(m, n) (((m) > (n)) ? (m) : (n))
Return the maximum of two values.
-
INTN_ADD_OUT_LEN(m, n) ((MAX_LEN(m, n)) + 1)
Calculate output buffer size needed for addition.
- Parameters:
m – Length of first operand in digits
n – Length of second operand in digits
- Returns:
Maximum possible output length in digits
-
INTN_SUB_OUT_LEN(m, n) ((MAX_LEN(m, n)) + 1)
Calculate output buffer size needed for subtraction.
- Parameters:
m – Length of minuend in digits
n – Length of subtrahend in digits
- Returns:
Maximum possible output length in digits
-
INTN_MUL_OUT_LEN(m, n) ((m) + (n))
Calculate output buffer size needed for multiplication.
Note
Result always has exactly m + n digits (some may be zero)
- Parameters:
m – Length of first operand in digits
n – Length of second operand in digits
- Returns:
Maximum possible output length in digits
-
INTN_REM_OUT_LEN(m, n) (n)
Calculate output buffer size needed for remainder.
- Parameters:
m – Length of dividend in digits
n – Length of divisor in digits
- Returns:
Maximum possible remainder length in digits
-
INTN_DIV_OUT_LEN(m, n) ((m) - (n) + 1 + 1)
Calculate output buffer size needed for division quotient.
- Parameters:
m – Length of dividend in digits
n – Length of divisor in digits
- Returns:
Maximum possible quotient length in digits
-
INTN_DIGIT_BITS 32
Number of bits in each digit (32 bits in current implementation)
-
INTN_MAX_UNSIGNED_BYTES_SIZE 32
Maximum size in bytes for unsigned integer representation (256 bits / 8)
-
INTN_MAX_UNSIGNED_BITS_SIZE 256
Maximum size in bits for unsigned integer representation.
Typedefs
-
typedef uint32_t intn_digit_t
Single digit of a multi-precision integer.
Currently 32 bits, but this is an implementation detail that may change. Always use
intn_digit_ttype and related macros rather than assuming size.
Enums
Functions
-
int intn_cmp(const intn_digit_t a[], size_t a_len, const intn_digit_t b[], size_t b_len)
Compare two unsigned multi-precision integers.
Compares the magnitude of two multi-precision integers, ignoring sign. Accepts both normalized and non-normalized inputs.
Note
Leading zeros are ignored in comparison
Note
Accepts both normalized and non-normalized inputs
- Parameters:
a – First integer array
a_len – Length of first integer in digits
b – Second integer array
b_len – Length of second integer in digits
- Returns:
-1 if a < b, 0 if a == b, 1 if a > b
-
size_t intn_addu(const intn_digit_t a[], size_t a_len, const intn_digit_t b[], size_t b_len, intn_digit_t out[])
Add two unsigned multi-precision integers.
Performs addition of magnitudes only, without considering signs (similar to unsigned addition).
Note
Accepts both normalized and non-normalized inputs
- Parameters:
a – First addend
a_len – Length of first addend in digits
b – Second addend
b_len – Length of second addend in digits
out – [out] Result buffer (must have at least
INTN_ADD_OUT_LEN(a_len, b_len)digits)
- Returns:
Actual length of result in digits (may be less than buffer size)
- Pre:
out buffer must be at least
INTN_ADD_OUT_LEN(a_len, b_len)digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_add(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Add two signed multi-precision integers.
Performs signed addition of two multi-precision integers with separate signs.
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – First addend magnitude
m_len – Length of first addend in digits
m_sign – Sign of first addend
n – Second addend magnitude
n_len – Length of second addend in digits
n_sign – Sign of second addend
out – [out] Result buffer (must have at least
INTN_ADD_OUT_LEN(m_len, n_len)digits)out_sign – [out] Sign of result
- Returns:
Actual length of result in digits (may be less than buffer size)
- Pre:
out buffer must be at least
INTN_ADD_OUT_LEN(m_len, n_len)digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_add_int64(int64_t num1, int64_t num2, intn_digit_t *out, intn_integer_sign_t *out_sign)
Add two 64-bit signed integers (
int64_t) producing multi-precision result.Specialized addition for
int64_tvalues that may overflow.- Parameters:
num1 – First 64-bit addend
num2 – Second 64-bit addend
out – [out] Result buffer (must have at least
INTN_ADD_OUT_LEN(INTN_INT64_LEN,INTN_INT64_LEN)digits)out_sign – [out] Sign of result
- Returns:
Actual length of result in digits
- Pre:
out buffer must be at least
INTN_ADD_OUT_LEN(INTN_INT64_LEN, INTN_INT64_LEN)digits
-
size_t intn_subu(const intn_digit_t a[], size_t a_len, const intn_digit_t b[], size_t b_len, intn_digit_t out[])
Subtract two unsigned multi-precision integers.
Performs subtraction of magnitudes only (a - b) where a must be >= b.
Note
Accepts both normalized and non-normalized inputs
- Parameters:
a – Minuend (must be >= b)
a_len – Length of minuend in digits
b – Subtrahend
b_len – Length of subtrahend in digits
out – [out] Result buffer (must have at least
INTN_SUB_OUT_LEN(a_len, b_len)digits)
- Returns:
Actual length of result in digits (may be less than buffer size)
- Pre:
a >= b (use
intn_cmpto verify if needed)- Pre:
out buffer must be at least
INTN_SUB_OUT_LEN(a_len, b_len)digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_sub(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Subtract two signed multi-precision integers.
Performs signed subtraction (m - n) with separate signs.
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – Minuend magnitude
m_len – Length of minuend in digits
m_sign – Sign of minuend
n – Subtrahend magnitude
n_len – Length of subtrahend in digits
n_sign – Sign of subtrahend
out – [out] Result buffer (must have at least
INTN_SUB_OUT_LEN(m_len, n_len)digits)out_sign – [out] Sign of result
- Returns:
Actual length of result in digits (may be less than buffer size)
- Pre:
out buffer must be at least
INTN_SUB_OUT_LEN(m_len, n_len)digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_sub_int64(int64_t num1, int64_t num2, intn_digit_t *out, intn_integer_sign_t *out_sign)
Subtract two 64-bit signed integers (
int64_t) producing multi-precision result.Specialized subtraction for
int64_tvalues that may overflow.- Parameters:
num1 – Minuend
num2 – Subtrahend
out – [out] Result buffer (must have at least
INTN_SUB_OUT_LEN(INTN_INT64_LEN,INTN_INT64_LEN)digits)out_sign – [out] Sign of result
- Returns:
Actual length of result in digits
- Pre:
out buffer must be at least
INTN_SUB_OUT_LEN(INTN_INT64_LEN, INTN_INT64_LEN)digits
-
static inline intn_integer_sign_t intn_muldiv_sign(intn_integer_sign_t s1, intn_integer_sign_t s2)
Compute sign of multiplication or division result.
Applies standard sign rules: same signs give positive, different signs give negative.
- Parameters:
s1 – Sign of first operand
s2 – Sign of second operand
- Returns:
Sign of the result
-
void intn_mulu(const intn_digit_t m[], size_t m_len, const intn_digit_t n[], size_t n_len, intn_digit_t out[])
Multiply two unsigned multi-precision integers.
Performs multiplication of magnitudes only, without considering signs.
Note
Accepts both normalized and non-normalized inputs
Note
Based on algorithms from Hacker’s Delight
- Parameters:
m – First multiplicand
m_len – Length of first multiplicand in digits
n – Second multiplicand
n_len – Length of second multiplicand in digits
out – [out] Result buffer (must have at least
INTN_MUL_OUT_LEN(m_len, n_len)digits)
- Pre:
out buffer must be at least
INTN_MUL_OUT_LEN(m_len, n_len)digits- Post:
Exactly m_len + n_len digits are written (some may be zero)
- Post:
Result may have leading zeros (not normalized)
-
static inline void intn_mul(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Multiply two signed multi-precision integers.
Performs signed multiplication with separate signs.
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – First multiplicand magnitude
m_len – Length of first multiplicand in digits
m_sign – Sign of first multiplicand
n – Second multiplicand magnitude
n_len – Length of second multiplicand in digits
n_sign – Sign of second multiplicand
out – [out] Result buffer (must have at least
INTN_MUL_OUT_LEN(m_len, n_len)digits)out_sign – [out] Sign of result
- Pre:
out buffer must be at least
INTN_MUL_OUT_LEN(m_len, n_len)digits- Post:
Exactly m_len + n_len digits are written (some may be zero)
- Post:
Result may have leading zeros (not normalized)
-
void intn_mul_int64(int64_t num1, int64_t num2, intn_digit_t *out, intn_integer_sign_t *out_sign)
Multiply two 64-bit signed integers (
int64_t) producing multi-precision result.Specialized multiplication for
int64_tvalues that may overflow.- Parameters:
num1 – First multiplicand
num2 – Second multiplicand
out – [out] Result buffer (must have at least
INTN_MUL_OUT_LEN(INTN_INT64_LEN,INTN_INT64_LEN)digits)out_sign – [out] Sign of result
- Pre:
out buffer must be at least
INTN_MUL_OUT_LEN(INTN_INT64_LEN, INTN_INT64_LEN)digits- Post:
Exactly INTN_INT64_LEN + INTN_INT64_LEN digits are written
-
size_t intn_divu(const intn_digit_t m[], size_t m_len, const intn_digit_t n[], size_t n_len, intn_digit_t q_out[], intn_digit_t r_out[], size_t *r_out_len)
Divide two unsigned multi-precision integers with optional remainder.
Performs division of magnitudes m / n, computing quotient and optionally remainder.
Note
Accepts both normalized and non-normalized inputs
Note
Based on algorithms from Hacker’s Delight
- Parameters:
m – Dividend
m_len – Length of dividend in digits
n – Divisor (must not be zero)
n_len – Length of divisor in digits
q_out – [out] Quotient buffer (must have at least
INTN_DIV_OUT_LEN(m_len, n_len)digits)r_out – [out] Remainder buffer (may be NULL, else must have at least
INTN_REM_OUT_LEN(m_len, n_len)digits)r_out_len – [out] Length of remainder (may be NULL if r_out is NULL)
- Returns:
Length of quotient in digits
- Pre:
n must not be zero
- Pre:
q_out buffer must be at least
INTN_DIV_OUT_LEN(m_len, n_len)digits- Pre:
r_out buffer (if not NULL) must be at least
INTN_REM_OUT_LEN(m_len, n_len)digits- Post:
Quotient and remainder may have leading zeros (not normalized)
-
static inline size_t intn_div(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t q_out[], intn_integer_sign_t *qout_sign, intn_digit_t r_out[], size_t *r_out_len)
Divide two signed multi-precision integers with optional remainder.
Performs signed division m / n with separate signs.
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – Dividend magnitude
m_len – Length of dividend in digits
m_sign – Sign of dividend
n – Divisor magnitude (must not be zero)
n_len – Length of divisor in digits
n_sign – Sign of divisor
q_out – [out] Quotient buffer (must have at least
INTN_DIV_OUT_LEN(m_len, n_len)digits)qout_sign – [out] Sign of quotient
r_out – [out] Remainder buffer (may be NULL, else must have at least
INTN_REM_OUT_LEN(m_len, n_len)digits)r_out_len – [out] Length of remainder (may be NULL if r_out is NULL)
- Returns:
Length of quotient in digits
- Pre:
n must not be zero
- Pre:
q_out buffer must be at least
INTN_DIV_OUT_LEN(m_len, n_len)digits- Pre:
r_out buffer (if not NULL) must be at least
INTN_REM_OUT_LEN(m_len, n_len)digits- Post:
Remainder has same sign as dividend (Euclidean division)
-
size_t intn_bor(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Bitwise OR of two signed multi-precision integers.
Performs bitwise OR by internally converting to two’s complement, applying the operation, then converting back to sign-magnitude form.
// Example: 0xFFFFFFFF00000000000012345678 | -1 // Input: {0x12345678, 0x0, 0xFFFF0000, 0xFFFF} | {0x1} with negative sign // Internal two's complement: {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} // Result: {0x1, 0x0, 0x0, 0x0} with negative sign (equals -1)
Note
Input and output are in sign-magnitude form, not two’s complement
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – First operand magnitude
m_len – Length of first operand in digits
m_sign – Sign of first operand
n – Second operand magnitude
n_len – Length of second operand in digits
n_sign – Sign of second operand
out – [out] Result buffer (must have at least
MAX_LEN(m_len, n_len)+ 1 digits)out_sign – [out] Sign of result
- Returns:
Length of result in digits
- Pre:
out buffer must be at least
MAX_LEN(m_len, n_len)+ 1 digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_band(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Bitwise AND of two signed multi-precision integers.
Performs bitwise AND by internally converting to two’s complement, applying the operation, then converting back to sign-magnitude form.
// Example: 0xFFFFFFFFF123456789ABFFFFFFFF & -0xFFFFFFFF000000000000FFFFFFFF // Input: {0xFFFFFFFF, 0x456789AB, 0xFFFFF123, 0xFFFF} & // {0xFFFFFFFF, 0x0, 0xFFFF0000, 0xFFFF} with negative sign // Result: {0x1, 0x456789AB, 0xF123} (equals 0xF123456789AB00000001)
Note
Input and output are in sign-magnitude form, not two’s complement
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – First operand magnitude
m_len – Length of first operand in digits
m_sign – Sign of first operand
n – Second operand magnitude
n_len – Length of second operand in digits
n_sign – Sign of second operand
out – [out] Result buffer (must have at least
MAX_LEN(m_len, n_len)+ 1 digits)out_sign – [out] Sign of result
- Returns:
Length of result in digits
- Pre:
out buffer must be at least
MAX_LEN(m_len, n_len)+ 1 digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_bxor(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, const intn_digit_t n[], size_t n_len, intn_integer_sign_t n_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Bitwise XOR of two signed multi-precision integers.
Performs bitwise XOR by internally converting to two’s complement, applying the operation, then converting back to sign-magnitude form.
// Example: 0xFFFFFFFF00000000000012345678 ^ -1 // Input: {0x12345678, 0x0, 0xFFFF0000, 0xFFFF} ^ {0x1} with negative sign // Result: {0x12345679, 0x0, 0xFFFF0000, 0xFFFF} with negative sign
Note
Input and output are in sign-magnitude form, not two’s complement
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – First operand magnitude
m_len – Length of first operand in digits
m_sign – Sign of first operand
n – Second operand magnitude
n_len – Length of second operand in digits
n_sign – Sign of second operand
out – [out] Result buffer (must have at least
MAX_LEN(m_len, n_len)+ 1 digits)out_sign – [out] Sign of result
- Returns:
Length of result in digits
- Pre:
out buffer must be at least
MAX_LEN(m_len, n_len)+ 1 digits- Post:
Result may have leading zeros (not normalized)
-
size_t intn_bnot(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_sign, intn_digit_t out[], intn_integer_sign_t *out_sign)
Bitwise NOT of a signed multi-precision integer.
Performs bitwise NOT operation (one’s complement).
Note
Accepts both normalized and non-normalized inputs
- Parameters:
m – Operand magnitude
m_len – Length of operand in digits
m_sign – Sign of operand
out – [out] Result buffer (must have at least m_len + 1 digits)
out_sign – [out] Sign of result
- Returns:
Length of result in digits
- Pre:
out buffer must be at least m_len + 1 digits
- Post:
Result may have leading zeros (not normalized)
-
size_t intn_bsl(const intn_digit_t num[], size_t len, size_t n, intn_digit_t *out)
Bit shift left of multi-precision integer.
Shifts integer left by n bit positions.
Note
Accepts both normalized and non-normalized inputs
Warning
If return value >
INTN_BSL_MAX_RES_LEN, result overflowed and out buffer was not written. Caller must check return value before using result.- Parameters:
num – Integer to shift
len – Length of integer in digits
n – Number of bit positions to shift
out – [out] Result buffer (must have sufficient space, see warning)
- Returns:
Length of result in digits
- Pre:
out buffer must be at least
INTN_BSL_MAX_RES_LENdigits when shift is reasonable- Post:
Result may have leading zeros (not normalized)
-
size_t intn_bsr(const intn_digit_t num[], size_t len, intn_integer_sign_t num_sign, size_t n, intn_digit_t *out)
Bit shift right of signed multi-precision integer.
Performs arithmetic right shift (sign-extending) by n bit positions.
Note
Follows Erlang semantics: large shifts converge to -1 (negative) or 0 (non-negative)
Note
Accepts both normalized and non-normalized inputs
- Parameters:
num – Integer magnitude to shift
len – Length of integer in digits
num_sign – Sign of integer
n – Number of bit positions to shift
out – [out] Result buffer (must have at least len digits)
- Returns:
Length of result in digits
- Pre:
out buffer must be at least len digits
- Post:
Result may have leading zeros (not normalized)
-
size_t intn_count_digits(const intn_digit_t *num, size_t num_len)
Count non-zero digits in multi-precision integer.
Returns the number of significant (non-zero) digits, effectively normalizing the length. This is used to determine the actual size of a result after an operation that may produce leading zeros.
Note
Essential for normalization after operations
// Examples: intn_count_digits({0x0, 0x0, 0x0, 0x80000000}, 4) -> 4 (no leading zeros) intn_count_digits({0x0, 0x0, 0x0, 0x80000000, 0x0}, 5) -> 4 (one leading zero)
- Parameters:
num – Integer array to count
num_len – Length of array in digits
- Returns:
Number of non-zero digits (0 if integer is zero)
-
char *intn_to_string(const intn_digit_t *num, size_t len, intn_integer_sign_t num_sign, int base, size_t *string_len)
Convert multi-precision integer to string.
Converts integer to ASCII string representation in specified base. Output uses uppercase letters for digits > 9, with no base prefix (e.g., no “0x”).
Note
Output format: uppercase letters, no base prefix
Note
Accepts both normalized and non-normalized inputs
- Parameters:
num – Integer magnitude (must be normalized)
len – Length of integer in digits
num_sign – Sign of integer
base – Number base for conversion (2-36)
string_len – [out] Length of resulting string (not including null terminator)
- Returns:
Newly allocated null-terminated string (caller must free)
- Pre:
base >= 2 && base <= 36
- Post:
Returned string must be freed by caller
-
int intn_parse(const char buf[], size_t buf_len, int base, intn_digit_t *out, intn_integer_sign_t *out_sign)
Parse ASCII string to multi-precision integer.
Parses integer from ASCII representation in specified base. Supports chunk parsing for arbitrarily large integers.
Note
No base prefixes (like “0x”) are supported
Note
Leading zeros in input are skipped automatically
Note
Signs (+/-) accepted unless rejected by caller options
Note
Case-insensitive for letter digits (a-z, A-Z)
- Parameters:
buf – Buffer containing ASCII digits
buf_len – Length of buffer in bytes
base – Number base for parsing (2-36)
out – [out] Result buffer (must have at least
INTN_MAX_RES_LENdigits)out_sign – [out] Sign of parsed integer
- Returns:
Number of digits in result, or negative on parse error
- Pre:
base >= 2 && base <= 36
- Pre:
buf != NULL when buf_len > 0 (NULL allowed only for zero-length buffer)
- Pre:
out buffer must be at least
INTN_MAX_RES_LENdigits- Post:
Result may have leading zeros (not normalized)
-
double intn_to_double(const intn_digit_t *num, size_t len, intn_integer_sign_t sign)
Convert multi-precision integer to double.
Converts integer to floating-point representation. May lose precision for large integers.
Note
Precision loss expected for integers > 53 bits
Note
With current 256-bit limit, result always fits in double range
Note
Accepts both normalized and non-normalized inputs
- Parameters:
num – Integer magnitude (must be normalized)
len – Length of integer in digits
sign – Sign of integer
- Returns:
Double representation
-
int intn_from_double(double dnum, intn_digit_t *out, intn_integer_sign_t *out_sign)
Convert double to multi-precision integer.
Converts floating-point value to integer, truncating fractional part.
- Parameters:
dnum – Double value to convert
out – [out] Result buffer (must have sufficient space)
out_sign – [out] Sign of result
- Returns:
Number of digits in result, or negative on error
- Pre:
dnum must be finite (not NaN or infinity)
- Post:
Result may have leading zeros (not normalized)
-
int intn_from_integer_bytes(const uint8_t in[], size_t in_size, intn_from_integer_options_t opts, intn_digit_t out[], intn_integer_sign_t *out_sign)
Convert byte array to multi-precision integer.
Converts integer from byte representation with specified endianness and signedness.
- Parameters:
in – Input byte array
in_size – Size of input in bytes
opts – Conversion options (endianness, signedness)
out – [out] Result buffer (must have at least
intn_required_digits_for_unsigned_integer(in_size)digits)out_sign – [out] Sign of result
- Returns:
Number of digits in result, or negative on error
- Pre:
out buffer must have sufficient space based on in_size
- Post:
Result may have leading zeros (not normalized)
-
int intn_to_integer_bytes(const intn_digit_t in[], size_t in_len, intn_integer_sign_t in_sign, intn_from_integer_options_t opts, uint8_t out[], size_t out_len)
Convert multi-precision integer to byte array.
Converts integer to byte representation with specified endianness and signedness.
- Parameters:
in – Integer magnitude (must be normalized)
in_len – Length of integer in digits
in_sign – Sign of integer
opts – Conversion options (endianness, signedness)
out – [out] Output byte buffer
out_len – Size of output buffer in bytes
- Returns:
Number of bytes written, or negative on error (buffer too small)
- Pre:
Input must be normalized for correct size calculation
-
size_t intn_required_unsigned_integer_bytes(const intn_digit_t in[], size_t in_len)
Calculate bytes needed for unsigned integer representation.
Returns minimum number of bytes needed to represent the integer as an unsigned value.
- Parameters:
in – Integer magnitude (must be normalized)
in_len – Length of integer in digits
- Returns:
Number of bytes required
- Pre:
Input must be normalized for accurate result
-
static inline size_t intn_required_digits_for_unsigned_integer(size_t size_in_bytes)
Calculate digits needed for byte array.
Returns number of
intn_digit_tdigits needed to store an integer of given byte size.- Parameters:
size_in_bytes – Size of integer in bytes
- Returns:
Number of digits required
-
static inline intn_integer_sign_t intn_negate_sign(intn_integer_sign_t sign)
Negate sign of integer.
Flips the sign from positive to negative or vice versa.
- Parameters:
sign – Original sign
- Returns:
Negated sign
-
static inline void intn_copy(const intn_digit_t *num, size_t num_len, intn_digit_t *out, size_t extend_to)
Copy and optionally zero-extend multi-precision integer.
Copies integer to output buffer, padding with zeros if output buffer is larger than input.
- Parameters:
num – Source integer
num_len – Length of source in digits
out – [out] Destination buffer
extend_to – Size of destination buffer in digits
- Pre:
extend_to >= num_len
- Post:
Digits from num_len to extend_to are zeroed
-
static inline void intn_from_uint64(uint64_t absu64, intn_digit_t out[])
Convert
uint64_tto multi-precision integer.Converts unsigned 64-bit value to 2-digit representation.
- Parameters:
absu64 – Unsigned 64-bit value
out – [out] Output buffer (must have at least
INTN_UINT64_LENdigits)
- Pre:
out buffer must have at least
INTN_UINT64_LENdigits- Post:
Exactly
INTN_UINT64_LENdigits are written
-
static inline void intn_from_int64(int64_t i64, intn_digit_t out[], intn_integer_sign_t *out_sign)
Convert
int64_tto multi-precision integer.Converts signed 64-bit value to magnitude-sign representation.
- Parameters:
i64 – Signed 64-bit value
out – [out] Output buffer (must have at least
INTN_INT64_LENdigits)out_sign – [out] Sign of result
- Pre:
out buffer must have at least
INTN_INT64_LENdigits- Post:
Exactly
INTN_INT64_LENdigits are written
-
static inline uint64_t intn_to_uint64(const intn_digit_t num[])
Convert 2-digit multi-precision integer to
uint64_t.Extracts unsigned 64-bit value from 2-digit representation.
- Parameters:
num – Integer array (must have exactly 2 digits)
- Returns:
Unsigned 64-bit value
- Pre:
num must have exactly 2 digits
-
static inline int64_t intn_to_int64(const intn_digit_t num[], size_t len, intn_integer_sign_t sign)
Convert multi-precision integer to
int64_t.Converts magnitude-sign representation to signed 64-bit value.
Warning
Undefined behavior if value doesn’t fit in
int64_t- Parameters:
num – Integer magnitude (must be normalized)
len – Length of integer in digits
sign – Sign of integer
- Returns:
Signed 64-bit value
- Pre:
Integer must fit in
int64_trange (useintn_fits_int64to verify)- Pre:
Input must be normalized
-
static inline bool intn_fits_int64(const intn_digit_t num[], size_t len, intn_integer_sign_t sign)
Check if multi-precision integer fits in
int64_t.Tests whether integer can be represented as signed 64-bit value.
- Parameters:
num – Integer magnitude (must be normalized)
len – Length of integer in digits
sign – Sign of integer
- Returns:
true if fits in
int64_t, false otherwise- Pre:
Input must be normalized (no leading zeros)