1#!/usr/bin/perl 2 3use strict; 4use warnings; 5 6use Test::More 0.88; 7 8use Math::Int128 qw(uint128 uint128_to_number 9 net_to_uint128 uint128_to_net 10 native_to_uint128 uint128_to_native); 11 12my $i = uint128('1234567890123456789'); 13my $j = $i + 1; 14my $k = (uint128(1) << 60) + 255; 15 16# 1 17ok($i == '1234567890123456789'); 18 19ok($j - 1 == '1234567890123456789'); 20 21ok (($k & 127) == 127); 22 23ok (($k & 256) == 0); 24 25# 5 26ok ($i * 2 == $j + $j - 2); 27 28ok ($i * $i * $i * $i == ($j * $j - 2 * $j + 1) * ($j * $j - 2 * $j + 1)); 29 30ok (($i / $j) == 0); 31 32ok ($j / $i == 1); 33 34ok ($i % $j == $i); 35 36# 10 37ok ($j % $i == 1); 38 39ok (($j += 1) == $i + 2); 40 41ok ($j == $i + 2); 42 43ok (($j -= 3) == $i - 1); 44 45ok ($j == $i - 1); 46 47$j = $i; 48# 15 49ok (($j *= 2) == $i << 1); 50 51ok (($j >> 1) == $i); 52 53ok (($j / 2) == $i); 54 55$j = $i + 2; 56 57ok (($j %= $i) == 2); 58 59ok ($j == 2); 60 61# 20 62ok (($j <=> $i) < 0); 63 64ok (($i <=> $j) > 0); 65 66ok (($i <=> $i) == 0); 67 68ok (($j <=> 2) == 0); 69 70ok ($j < $i); 71 72# 25 73ok ($j <= $i); 74 75ok (!($i < $j)); 76 77ok (!($i <= $j)); 78 79ok ($i <= $i); 80 81ok ($j >= $j); 82 83# 30 84ok ($i > $j); 85 86ok ($i >= $j); 87 88ok (!($j > $i)); 89 90ok (!($j >= $i)); 91 92ok (int(log(uint128(1)<<50)/log(2)+0.001) == 50); 93 94# 35 95 96my $l = uint128("127131031961723452345"); 97 98is ("$l", "127131031961723452345", "string to/from int128 conversion"); 99 100ok (native_to_uint128(uint128_to_native(1)) == 1); 101 102ok (native_to_uint128(uint128_to_native(0)) == 0); 103 104ok (native_to_uint128(uint128_to_native(12343)) == 12343); 105 106ok (native_to_uint128(uint128_to_native($l)) == $l); 107 108# 40 109 110ok (native_to_uint128(uint128_to_native($j)) == $j); 111 112ok (native_to_uint128(uint128_to_native($i)) == $i); 113 114ok (net_to_uint128(uint128_to_net(1)) == 1); 115 116ok (net_to_uint128(uint128_to_net(0)) == 0); 117 118ok (net_to_uint128(uint128_to_net(12343)) == 12343); 119 120# 45 121 122ok (net_to_uint128(uint128_to_net($l)) == $l); 123 124ok (net_to_uint128(uint128_to_net($j)) == $j); 125 126ok (net_to_uint128(uint128_to_net($i)) == $i); 127 128{ 129 use integer; 130 my $int = uint128(255); 131 ok($int == 255); 132 $int <<= 32; 133 $int |= 4294967295; 134 ok($int == '1099511627775'); 135} 136 137my $two = uint128(2); 138my $four = uint128(4); 139is ($two ** -1, 0, "signed pow 2**-1"); 140is ($four ** -1, 0, "signed pow 4**-1"); 141 142sub slow_pow_uint128 { 143 my ($a, $b) = @_; 144 my $acu = uint128(1); 145 $acu *= $a for 1..$b; 146 $acu; 147} 148 149sub slow_pow_nv { 150 my ($base, $exp) = @_; 151 my $r = 1; 152 $r *= $base for 1..$exp; 153 $r 154} 155 156my $max = (((uint128(2) ** 127) - 1) * 2) + 1; 157for my $j (0..127) { 158 my $one = uint128(1); 159 160 is($two ** $j, $one << $j, "signed pow 2**$j"); 161 is($four ** $j, $one << 2 * $j, "signed pow 4**$j") if $j < 64; 162 163 is($one << $j, $two ** $j, "$one << $j"); 164 165 $one <<= $j; 166 is($one, $two ** $j, "$one <<= $j"); 167 168 next unless $j; 169 170 my $pow2j = slow_pow_nv(2, $j); 171 172 is($max >> $j, $max / $pow2j, "max uint128 >> $j"); 173 174 my $copy = uint128($max); 175 $copy >>= $j; 176 is($copy, $max / $pow2j, "max uint128 >>= $j"); 177} 178 179for my $i (5..9) { 180 for my $j (0..40) { # 9**40 < 2**127 181 is(uint128($i) ** $j, slow_pow_uint128($i, $j), "signed pow $i ** $j"); 182 } 183} 184 185done_testing(); 186