Modern system programming frequently requires numbers larger than 64 bits. IPv6 addresses, UUIDs, cryptography algorithms, and specialized high-precision timers rely on 128-bit integers (__int128_t or unsigned __int128 in GCC/Clang).

Perl natively supports a maximum of 64-bit integers (IV). If you try to stuff a 128-bit number into a standard Perl scalar, Perl will silently truncate it or convert it to a floating-point number (NV), permanently destroying your low-level bit precision.

Affix solves this seamlessly by automatically marshaling 128-bit C integers to and from Perl Strings, preserving absolute precision.

The Recipe

We will write a C function that multiplies two huge 128-bit integers and returns the result, validating that no precision is lost crossing the FFI boundary.

use v5.40;
use Affix qw[:all];
use Affix::Build;

my $c = Affix::Build->new();
$c->add( \<<~'C', lang => 'c' );
    // Define standard 128-bit types supported by GCC/Clang
    typedef unsigned __int128 uint128_t;

    uint128_t multiply_huge(uint128_t a, uint128_t b) {
        return a * b;
    }
C

my $lib = $c->link;

# 1. Bind using the 128-bit types
affix $lib, 'multiply_huge',[ UInt128, UInt128 ] => UInt128;

# 2. Define massive numbers as Strings
# 18,446,744,073,709,551,615 is the maximum 64-bit unsigned integer
my $huge_a = "18446744073709551615";
my $huge_b = "5";

# 3. Execute
my $result = multiply_huge( $huge_a, $huge_b );

say "$huge_a * $huge_b = $result";
# Output: 18446744073709551615 * 5 = 92233720368547758075

How It Works

Kitchen Reminders