Affix
view release on metacpan or search on metacpan
t/009_128bit.t view on Meta::CPAN
use v5.40;
use lib '../lib', 'lib';
use blib;
use Test2::Tools::Affix qw[:all];
use Affix qw[:all];
#
$|++;
#
my $c_source = <<'END_C';
#include "std.h"
//ext: .c
#include <stdio.h>
#include <stdint.h>
/* 128-bit Integers */
#ifdef __SIZEOF_INT128__
typedef __int128_t int128;
typedef __uint128_t uint128;
DLLEXPORT int has_int128() { return 1; }
DLLEXPORT int128 add_i128(int128 a, int128 b) {
return a + b;
}
DLLEXPORT uint128 add_u128(uint128 a, uint128 b) {
return a + b;
}
// Helper to verify value passed correctly (returns high 64 bits cast to 64)
DLLEXPORT int64_t high_bits_i128(int128 v) {
return (int64_t)(v >> 64);
}
#else
DLLEXPORT int has_int128() { return 0; }
#endif
END_C
# Compile the library
my $lib = compile_ok($c_source);
# Check if the C compiler supported it
my $check = wrap( $lib, 'has_int128', [] => Int );
if ( !$check->() ) {
skip_all "Compiler does not support __int128_t";
}
# Bind functions
# Note: Passed/Returned as Strings in Perl
isa_ok my $add_i = wrap( $lib, 'add_i128', [ Int128, Int128 ] => Int128 ), ['Affix'];
isa_ok my $add_u = wrap( $lib, 'add_u128', [ UInt128, UInt128 ] => UInt128 ), ['Affix'];
isa_ok my $high = wrap( $lib, 'high_bits_i128', [Int128] => Int64 ), ['Affix'];
# Test Signed Addition
# 2^100 approx 1.26e30
my $v1 = "1267650600228229401496703205376";
my $v2 = "1";
my $sum = $add_i->( $v1, $v2 );
is $sum, "1267650600228229401496703205377", "Signed 128-bit add worked";
# Test Unsigned Overflow wrapping (if applicable) or just large numbers
( run in 2.094 seconds using v1.01-cache-2.11-cpan-437f7b0c052 )