This header-only C++ library provides an arbitrary-fixed-width integer type called bigint. It supports both signed and unsigned numbers with a customizable bit-width. The class implements a wide range of arithmetic, bitwise, and comparison operators, making it suitable for tasks that require precise control over large integers.
- Customizable Bit-Width:
 Define yourbigintwith a specific number of bits (must be a multiple of 8).
- Signed and Unsigned Support:
 Use the template parameteris_signedto select between signed (two’s complement) and unsigned behavior.
- Arithmetic Operators:
- Addition (+,+=)
- Subtraction (-,-=)
- Multiplication (*,*=)
- Division (/,/=)
- Modulus (%,%=)
 
- Addition (
- Unary Operators:
- Unary minus (-) which computes two’s complement for signed values
- Increment and Decrement (prefix and postfix)
 
- Unary minus (
- Bitwise Operators:
- AND (&,&=)
- OR (|,|=)
- XOR (^,^=)
- NOT (~)
 
- AND (
- Shift Operators:
- Left Shift (<<,<<=)
- Right Shift (>>,>>=)
 
- Left Shift (
- Comparison Operators:
 Supports three-way comparisons (<=>) for bothbigints and built-in integral types.
- String Initialization:
 Initialize from strings representing decimal, hexadecimal (prefix0x), binary (prefix0b), and octal numbers. Negative decimal values are supported for signed types.
Simply include the header in your project:
#include "bigint.hpp"Construct a bigint from an integral type or a string:
// Create a 128-bit signed bigint from an integer:
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> a(123456789);
// Create a 128-bit unsigned bigint from a decimal string:
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Unsigned> b("9876543210");
// Create a 128-bit signed bigint from a hexadecimal string:
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> c("0x1A2B3C4D");The bigint class overloads many operators, allowing you to use familiar C++ syntax:
auto sum   = a + b;
auto diff  = a - c;
auto prod  = a * c;
auto quot  = b / 12345;
auto mod   = b % a;
a += 100;
a -= 50;
a *= -3;
a /= 7;
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> d = ~a;   // Bitwise NOT
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> e = a & c;  // Bitwise AND
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> f = a | c;  // Bitwise OR
bigint::bigint<bigint::BitWidth{128}, bigint::Signedness::Signed> g = a ^ c;  // Bitwise XOR
a <<= 4;  // Left shift
b >>= 8;  // Right shift
if (a < b) {
    // Comparison
}Compare bigints or built-in integers using the three-way comparison operator:
if (a < 1000) {
    // ...
}
if (a == b) {
    // ...
}- Internal Representation: The number is stored as an array of bytes (std::array<std::uint8_t, bits / CHAR_BIT>) in native endianness. Operators are implemented to be endianness-aware.
- Arithmetic Algorithms:
- Multiplication: Uses a school-book algorithm with proper carry propagation.
- Division and Modulus: Use a binary long-division algorithm that operates on each bit.
 
- Overflow Handling: Some helper operations (like multiplication and addition) throw std::overflow_errorif an operation produces a result that exceeds the fixed width.
- Two's Complement: For signed bigints, negative numbers are stored in two's complement form. The unary minus operator (operator-()) computes this by inverting the bits and adding one.
This is a header-only library that requires a C++20-compliant compiler (for features like concepts, <=> and std::endian). To compile your project use a command such as:
g++ -std=c++20 -O2 -Wall your_program.cpp -o your_programContributions, bug reports, and feature requests are welcome! Feel free to open an issue or submit a pull request.
- Fork it!
- Create your feature branch: git checkout -b feature/my-new-feature
- Commit your changes: git commit -am 'Add some feature'
- Push to the branch: git push origin feature/my-new-feature
- Submit a pull request
This project is licensed under the MIT License.