Bigint: Fixed-Width Large Integers

LibExcessive provides a suite of fixed-width large integer types (e.g., 128, 256, 512 bits) optimized for high-performance applications that require exact bit-widths without the overhead of dynamic heap allocations. These types behave similarly to built-in C++ integer types but support much larger ranges.

Characteristics

UnsignedFixedWidthBigInt is designed to be a drop-in replacement for standard integers in performance-critical code:

Usage Example

#include "bigint.h"
#include <iostream>

void bigintExample() {
    // Construct from hex strings
    uint256_t a("0xFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
    uint256_t b("0x1234567890ABCDEF1234567890ABCDEF");

    // Standard arithmetic
    uint256_t sum = a + b;
    uint256_t prod = a * b;

    // Advanced math
    uint256_t b_pow_4 = b.pow(4);
    uint256_t a_sqrt = a.root(2);

    // Conversion to string (produces "0x1204567890ABCDEF1234567890ABCDEE")
    std::cout << "Sum: " << std::string(sum) << std::endl;
}

API Reference: UnsignedFixedWidthBigInt

The template parameter N defines the number of 64-bit chunks (e.g., N=4 for a 256-bit integer).

Common Type Aliases

Constructors

Arithmetic Operators

Bitwise Operators

Math Functions

Conversions and Output


How it Works: Technical Overview

UnsignedFixedWidthBigInt implements multi-precision arithmetic by treating a large integer as a base-$2^{64}$ number.

Memory Representation

The internal state is stored in a union containing an array of uint64_t (the chunks) and a corresponding raw byte array. Chunks are stored in little-endian order (least significant chunk at index 0), which aligns with common CPU architectures like x86_64. This layout allows for efficient indexing and interaction with standard integer registers.

Arithmetic Implementation

Floating-Point Interop

The toDouble and fromDouble conversions work by extracting the most significant bits of the large integer and adjusting the exponent of the IEEE 754 double-precision format. Multiplication with a double (operator*) is performed by scaling the large integer in its base-$2^{64}$ form, effectively performing a fixed-point multiplication where the double provides the scaling factor. This makes double multiplication extremely accurate.