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
-
1. String to
__int128(Input) When you pass a string to aUInt128orSInt128argument, Affix's internal_alt_sv_to_int128parser takes over. It iterates through the string character-by-character, accumulating the value using native 128-bit math inside the C engine. It automatically detects and handles negative signs (-) and trims leading whitespace. -
2.
__int128to String (Output) When the C function returns, thevtbl_uint128magic hook intercepts the raw 128-bit register value. Because Perl cannot hold this natively, Affix runs a modulo-10 division loop in C (alt_int128_to_sv), serializing the massive number into a base-10 ASCII string before handing the scalar back to your Perl script.
Kitchen Reminders
- Hexadecimal Support
Affix's 128-bit parser is smart. If you prefer to work in hex (common for IPv6 or UUIDs), you can pass a string prefixed with
0x. Affix will automatically switch to base-16 parsing:my $uuid_part = "0xDEADBEEFCAFEBABEFACE"; multiply_huge($uuid_part, "2"); - Math in Perl
Because Affix hands you back a String, you cannot use native Perl operators (
+,-,*) on the result without overflowing Perl's 64-bit limits. If you need to manipulate the returned 128-bit numbers further inside your Perl script, you must useMath::BigIntoruse bignum;. - Compiler Support
128-bit integers are heavily supported by GCC and Clang, but MSVC (Microsoft Visual C++) does not natively support
__int128. If your Affix script is meant to be portable to MSVC on Windows, you may need to pass arrays of 64-bit integers instead.
Comments