The tiny Big Integer Library (released "as is", into the public domain, without any warranty, express or implied) is provided for handling large integers. It includes a variety of basic and advanced mathematical functions to support calculations. This solution does not use global variables but computation sheets, so it is stateless and thread-safe.
To build the executable, macOS and Linux users should use the Terminal, while Windows users should use PowerShell. The procedure takes just a few minutes :
- Open a Terminal or PowerShell.
- Navigate to the directory containing the source code using the
cd
command. - Compile the demo using the command
gcc -Wall -pedantic -O2 -std=c99 main.c -o demo
.
If gcc
is not installed on Windows, you can install MinGW, which provides it. Then, simply replace demo
with demo.exe
in the command above.
- macOS users: Replace
gcc
withclang
, which acts the same and is available natively. - Linux users: Install
gcc
withsudo apt update && sudo apt install gcc
.
Compilation takes a few seconds, then you can start the demo :
- Windows:
./demo.exe
- macOS and Linux:
./demo
The software will quickly display the results of the tests.
Arithmetic identities ... [PASS]
Distributivity and Associativity ... [PASS]
Left and Right shifts ... [PASS]
String conversion ... [PASS]
Random generator ... [PASS]
Division ... [PASS]
Power and modulo ... [PASS]
Double precision numbers ... [PASS]
Corner cases ... [PASS]
Primality ... [PASS]
Completed with 10 success and 0 failures.
This library strikes a balance between real-world needs and code simplicity, it is most efficient when dealing with integers that are a few hundred bits long, but can handle large numbers such as computing 10000!. Designed to be lightweight, it consists of only about 1000 lines of code and has no dependencies, adhering to the C99 standard.
The cint
structure is used to represent large integers, with its value stored in a dynamically allocated array of h_cint_t
(typically int64_t
):
typedef struct {
h_cint_t *mem; // Memory storing the least significant bits (little-endian format)
h_cint_t *end; // Memory storing the most significant bits (end-1)
h_cint_t nat; // -1 for negative, +1 for positive (zero is positive)
size_t size; // Allocated size, at least (end - mem)
} cint;
The cint_sheet
structure is used to manage temporary variables required for certain operations. It allows efficient memory usage when performing computations that require multiple intermediate results.
typedef struct {
cint temp[10]; // Array of temporary variables for large number operations
} cint_sheet;
-
cint_new_sheet(size_t bits)
Allocates a newcint_sheet
for storing temporary variables needed during calculations. -
cint_clear_sheet(cint_sheet *sheet)
Clears the memory used by acint_sheet
, releasing all allocated resources. -
h_cint_tmp(cint_sheet *sheet, int id, const cint *least)
Allocates memory for a temporarycint
variable within the providedcint_sheet
.
-
cint_init(cint *num, size_t bits, long long int val)
Initializes acint
with a specific size (in bits) and a long integer value. -
cint_init_by_string(cint *num, size_t bits, const char *str, int base)
Initializes acint
from a string representation of a number in a given base. -
cint_to_int(cint *num)
Converts acint
to a standardlong long int
(64-bit), truncating the value if necessary. -
cint_to_string(const cint *num, int base)
Converts acint
to a string in the specified base (e.g., decimal, hexadecimal).
These operations modify the original cint
(in-place), meaning the result of the operation is stored directly in one of the input variables:
-
cint_addi(cint *lhs, const cint *rhs)
Addsrhs
tolhs
in place. -
cint_subi(cint *lhs, const cint *rhs)
Subtractsrhs
fromlhs
in place. -
cint_muli(cint *lhs, const cint *rhs)
Multiplieslhs
byrhs
in place. -
cint_divi(cint *lhs, const cint *rhs)
Divideslhs
byrhs
in place. -
cint_left_shifti(cint *num, size_t bits)
Left shiftsnum
by the specified number of bits. -
cint_right_shifti(cint *num, size_t bits)
Right shiftsnum
by the specified number of bits.
-
cint_mul_mod(cint_sheet *sheet, const cint *lhs, const cint *rhs, const cint *mod, cint *res)
Computes the product oflhs
andrhs
modulomod
, storing the result inres
. -
cint_pow_mod(cint_sheet *sheet, const cint *n, const cint *exp, const cint *mod, cint *res)
Computesn
raised to the powerexp
modulomod
, storing the result inres
. -
cint_modular_inverse(cint_sheet *sheet, const cint *lhs, const cint *rhs, cint *res)
Computes the modular inverse oflhs
modulorhs
, storing the result inres
.
-
cint_is_prime(cint_sheet *sheet, const cint *N, int iterations, uint64_t *seed)
Uses the Miller-Rabin primality test to check ifN
is prime. Temporary variables are allocated fromsheet
. -
cint_gcd(cint_sheet *sheet, const cint *lhs, const cint *rhs, cint *gcd)
Computes the greatest common divisor (GCD) oflhs
andrhs
, storing the result ingcd
. -
cint_sqrt(cint_sheet *sheet, const cint *num, cint *res, cint *rem)
Computes the square root ofnum
, storing the result inres
and the remainder inrem
.
-
cint_checksum(const cint *num)
Computes a checksum for the givencint
. -
cint_count_bits(const cint *num)
Returns the number of bits required to representnum
. -
cint_count_zeros(const cint *num)
Returns the number of trailing zeros innum
. -
cint_compare(const cint *lhs, const cint *rhs)
Compares twocint
values. -
cint_to_double(const cint *num)
Converts acint
to adouble
. -
cint_nth_root(cint_sheet *sheet, const cint *num, unsigned nth, cint *res)
Computes the nth root ofnum
, storing the result inres
.
There is a GitHub project that uses this tiny Big Integer Library. It is a factorization software using the Quadratic Sieve, intended for users who enjoy mathematics applied to software. It can factor numbers up to 75 digits, and more.