1# -*- mode: perl; -*- 2 3# Test Math::BigInt::Calc 4 5use strict; 6use warnings; 7 8use Test::More tests => 524; 9 10use Math::BigInt::Calc; 11 12my ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, 13 $BASE_LEN_SMALL, $MAX_VAL, 14 $MAX_BITS, $MAX_EXP_F, $MAX_EXP_I, $USE_INT) 15 = Math::BigInt::Calc -> _base_len(); 16 17note(<<"EOF"); 18 19BASE_LEN = $BASE_LEN 20BASE = $BASE 21MAX_VAL = $MAX_VAL 22AND_BITS = $AND_BITS 23XOR_BITS = $XOR_BITS 24OR_BITS = $OR_BITS 25MAX_EXP_F = $MAX_EXP_F 26MAX_EXP_I = $MAX_EXP_I 27USE_INT = $USE_INT 28EOF 29 30my $LIB = 'Math::BigInt::Calc'; 31my $REF = 'Math::BigInt::Calc'; 32 33# _new and _str 34 35my $x = $LIB->_new("123"); 36my $y = $LIB->_new("321"); 37is(ref($x), $REF, q|ref($x) is a $REF|); 38is($LIB->_str($x), 123, qq|$LIB->_str(\$x) = 123|); 39is($LIB->_str($y), 321, qq|$LIB->_str(\$y) = 321|); 40 41############################################################################### 42# _add, _sub, _mul, _div 43 44is($LIB->_str($LIB->_add($x, $y)), 444, 45 qq|$LIB->_str($LIB->_add(\$x, \$y)) = 444|); 46is($LIB->_str($LIB->_sub($x, $y)), 123, 47 qq|$LIB->_str($LIB->_sub(\$x, \$y)) = 123|); 48is($LIB->_str($LIB->_mul($x, $y)), 39483, 49 qq|$LIB->_str($LIB->_mul(\$x, \$y)) = 39483|); 50is($LIB->_str($LIB->_div($x, $y)), 123, 51 qq|$LIB->_str($LIB->_div(\$x, \$y)) = 123|); 52 53############################################################################### 54# check that mul/div doesn't change $y 55# and returns the same reference, not something new 56 57is($LIB->_str($LIB->_mul($x, $y)), 39483, 58 qq|$LIB->_str($LIB->_mul(\$x, \$y)) = 39483|); 59is($LIB->_str($x), 39483, 60 qq|$LIB->_str(\$x) = 39483|); 61is($LIB->_str($y), 321, 62 qq|$LIB->_str(\$y) = 321|); 63 64is($LIB->_str($LIB->_div($x, $y)), 123, 65 qq|$LIB->_str($LIB->_div(\$x, \$y)) = 123|); 66is($LIB->_str($x), 123, 67 qq|$LIB->_str(\$x) = 123|); 68is($LIB->_str($y), 321, 69 qq|$LIB->_str(\$y) = 321|); 70 71$x = $LIB->_new("39483"); 72my ($x1, $r1) = $LIB->_div($x, $y); 73is("$x1", "$x", q|"$x1" = "$x"|); 74$LIB->_inc($x1); 75is("$x1", "$x", q|"$x1" = "$x"|); 76is($LIB->_str($r1), "0", qq|$LIB->_str(\$r1) = "0"|); 77 78$x = $LIB->_new("39483"); # reset 79 80############################################################################### 81 82my $z = $LIB->_new("2"); 83is($LIB->_str($LIB->_add($x, $z)), 39485, 84 qq|$LIB->_str($LIB->_add(\$x, \$z)) = 39485|); 85my ($re, $rr) = $LIB->_div($x, $y); 86 87is($LIB->_str($re), 123, qq|$LIB->_str(\$re) = 123|); 88is($LIB->_str($rr), 2, qq|$LIB->_str(\$rr) = 2|); 89 90# is_zero, _is_one, _one, _zero 91 92ok(! $LIB->_is_zero($x), qq|$LIB->_is_zero(\$x)|); 93ok(! $LIB->_is_one($x), qq|$LIB->_is_one(\$x)|); 94 95is($LIB->_str($LIB->_zero()), "0", qq|$LIB->_str($LIB->_zero()) = "0"|); 96is($LIB->_str($LIB->_one()), "1", qq|$LIB->_str($LIB->_one()) = "1"|); 97 98# _two() and _ten() 99 100is($LIB->_str($LIB->_two()), "2", qq|$LIB->_str($LIB->_two()) = "2"|); 101is($LIB->_str($LIB->_ten()), "10", qq|$LIB->_str($LIB->_ten()) = "10"|); 102 103ok(! $LIB->_is_ten($LIB->_two()), qq|$LIB->_is_ten($LIB->_two()) is false|); 104ok( $LIB->_is_two($LIB->_two()), qq|$LIB->_is_two($LIB->_two()) is true|); 105ok( $LIB->_is_ten($LIB->_ten()), qq|$LIB->_is_ten($LIB->_ten()) is true|); 106ok(! $LIB->_is_two($LIB->_ten()), qq|$LIB->_is_two($LIB->_ten()) is false|); 107 108ok( $LIB->_is_one($LIB->_one()), qq|$LIB->_is_one($LIB->_one()) is true|); 109ok(! $LIB->_is_one($LIB->_two()), qq|$LIB->_is_one($LIB->_two()) is false|); 110ok(! $LIB->_is_one($LIB->_ten()), qq|$LIB->_is_one($LIB->_ten()) is false|); 111 112ok(! $LIB->_is_one($LIB->_zero()), qq/$LIB->_is_one($LIB->_zero()) is false/); 113ok( $LIB->_is_zero($LIB->_zero()), qq|$LIB->_is_zero($LIB->_zero()) is true|); 114ok(! $LIB->_is_zero($LIB->_one()), qq/$LIB->_is_zero($LIB->_one()) is false/); 115 116# is_odd, is_even 117 118ok( $LIB->_is_odd($LIB->_one()), qq/$LIB->_is_odd($LIB->_one()) is true/); 119ok(! $LIB->_is_odd($LIB->_zero()), qq/$LIB->_is_odd($LIB->_zero()) is false/); 120ok(! $LIB->_is_even($LIB->_one()), qq/$LIB->_is_even($LIB->_one()) is false/); 121ok( $LIB->_is_even($LIB->_zero()), qq/$LIB->_is_even($LIB->_zero()) is true/); 122 123# _alen and _len 124 125for my $method (qw/_alen _len/) { 126 $x = $LIB->_new("1"); 127 is($LIB->$method($x), 1, qq|$LIB->$method(\$x) = 1|); 128 $x = $LIB->_new("12"); 129 is($LIB->$method($x), 2, qq|$LIB->$method(\$x) = 2|); 130 $x = $LIB->_new("123"); 131 is($LIB->$method($x), 3, qq|$LIB->$method(\$x) = 3|); 132 $x = $LIB->_new("1234"); 133 is($LIB->$method($x), 4, qq|$LIB->$method(\$x) = 4|); 134 $x = $LIB->_new("12345"); 135 is($LIB->$method($x), 5, qq|$LIB->$method(\$x) = 5|); 136 $x = $LIB->_new("123456"); 137 is($LIB->$method($x), 6, qq|$LIB->$method(\$x) = 6|); 138 $x = $LIB->_new("1234567"); 139 is($LIB->$method($x), 7, qq|$LIB->$method(\$x) = 7|); 140 $x = $LIB->_new("12345678"); 141 is($LIB->$method($x), 8, qq|$LIB->$method(\$x) = 8|); 142 $x = $LIB->_new("123456789"); 143 is($LIB->$method($x), 9, qq|$LIB->$method(\$x) = 9|); 144 145 $x = $LIB->_new("8"); 146 is($LIB->$method($x), 1, qq|$LIB->$method(\$x) = 1|); 147 $x = $LIB->_new("21"); 148 is($LIB->$method($x), 2, qq|$LIB->$method(\$x) = 2|); 149 $x = $LIB->_new("321"); 150 is($LIB->$method($x), 3, qq|$LIB->$method(\$x) = 3|); 151 $x = $LIB->_new("4321"); 152 is($LIB->$method($x), 4, qq|$LIB->$method(\$x) = 4|); 153 $x = $LIB->_new("54321"); 154 is($LIB->$method($x), 5, qq|$LIB->$method(\$x) = 5|); 155 $x = $LIB->_new("654321"); 156 is($LIB->$method($x), 6, qq|$LIB->$method(\$x) = 6|); 157 $x = $LIB->_new("7654321"); 158 is($LIB->$method($x), 7, qq|$LIB->$method(\$x) = 7|); 159 $x = $LIB->_new("87654321"); 160 is($LIB->$method($x), 8, qq|$LIB->$method(\$x) = 8|); 161 $x = $LIB->_new("987654321"); 162 is($LIB->$method($x), 9, qq|$LIB->$method(\$x) = 9|); 163 164 $x = $LIB->_new("0"); 165 is($LIB->$method($x), 1, qq|$LIB->$method(\$x) = 1|); 166 $x = $LIB->_new("20"); 167 is($LIB->$method($x), 2, qq|$LIB->$method(\$x) = 2|); 168 $x = $LIB->_new("320"); 169 is($LIB->$method($x), 3, qq|$LIB->$method(\$x) = 3|); 170 $x = $LIB->_new("4320"); 171 is($LIB->$method($x), 4, qq|$LIB->$method(\$x) = 4|); 172 $x = $LIB->_new("54320"); 173 is($LIB->$method($x), 5, qq|$LIB->$method(\$x) = 5|); 174 $x = $LIB->_new("654320"); 175 is($LIB->$method($x), 6, qq|$LIB->$method(\$x) = 6|); 176 $x = $LIB->_new("7654320"); 177 is($LIB->$method($x), 7, qq|$LIB->$method(\$x) = 7|); 178 $x = $LIB->_new("87654320"); 179 is($LIB->$method($x), 8, qq|$LIB->$method(\$x) = 8|); 180 $x = $LIB->_new("987654320"); 181 is($LIB->$method($x), 9, qq|$LIB->$method(\$x) = 9|); 182 183 for (my $i = 1; $i < 9; $i++) { 184 my $a = "$i" . '0' x ($i - 1); 185 $x = $LIB->_new($a); 186 is($LIB->_len($x), $i, qq|$LIB->_len(\$x) = $i|); 187 } 188} 189 190# _digit 191 192$x = $LIB->_new("123456789"); 193is($LIB->_digit($x, 0), 9, qq|$LIB->_digit(\$x, 0) = 9|); 194is($LIB->_digit($x, 1), 8, qq|$LIB->_digit(\$x, 1) = 8|); 195is($LIB->_digit($x, 2), 7, qq|$LIB->_digit(\$x, 2) = 7|); 196is($LIB->_digit($x, 8), 1, qq|$LIB->_digit(\$x, 8) = 1|); 197is($LIB->_digit($x, 9), 0, qq|$LIB->_digit(\$x, 9) = 0|); 198is($LIB->_digit($x, -1), 1, qq|$LIB->_digit(\$x, -1) = 1|); 199is($LIB->_digit($x, -2), 2, qq|$LIB->_digit(\$x, -2) = 2|); 200is($LIB->_digit($x, -3), 3, qq|$LIB->_digit(\$x, -3) = 3|); 201is($LIB->_digit($x, -9), 9, qq|$LIB->_digit(\$x, -9) = 9|); 202is($LIB->_digit($x, -10), 0, qq|$LIB->_digit(\$x, -10) = 0|); 203 204# _copy 205 206foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/) { 207 $x = $LIB->_new("$_"); 208 is($LIB->_str($LIB->_copy($x)), "$_", 209 qq|$LIB->_str($LIB->_copy(\$x)) = "$_"|); 210 is($LIB->_str($x), "$_", # did _copy destroy original x? 211 qq|$LIB->_str(\$x) = "$_"|); 212} 213 214# _zeros 215 216$x = $LIB->_new("1256000000"); 217is($LIB->_zeros($x), 6, qq|$LIB->_zeros(\$x) = 6|); 218 219$x = $LIB->_new("152"); 220is($LIB->_zeros($x), 0, qq|$LIB->_zeros(\$x) = 0|); 221 222$x = $LIB->_new("123000"); 223is($LIB->_zeros($x), 3, qq|$LIB->_zeros(\$x) = 3|); 224 225$x = $LIB->_new("0"); 226is($LIB->_zeros($x), 0, qq|$LIB->_zeros(\$x) = 0|); 227 228# _lsft, _rsft 229 230$x = $LIB->_new("10"); 231$y = $LIB->_new("3"); 232is($LIB->_str($LIB->_lsft($x, $y, 10)), 10000, 233 qq|$LIB->_str($LIB->_lsft(\$x, \$y, 10)) = 10000|); 234 235$x = $LIB->_new("20"); 236$y = $LIB->_new("3"); 237is($LIB->_str($LIB->_lsft($x, $y, 10)), 20000, 238 qq|$LIB->_str($LIB->_lsft(\$x, \$y, 10)) = 20000|); 239 240$x = $LIB->_new("128"); 241$y = $LIB->_new("4"); 242is($LIB->_str($LIB->_lsft($x, $y, 2)), 128 << 4, 243 qq|$LIB->_str($LIB->_lsft(\$x, \$y, 2)) = 128 << 4|); 244 245$x = $LIB->_new("1000"); 246$y = $LIB->_new("3"); 247is($LIB->_str($LIB->_rsft($x, $y, 10)), 1, 248 qq|$LIB->_str($LIB->_rsft(\$x, \$y, 10)) = 1|); 249 250$x = $LIB->_new("20000"); 251$y = $LIB->_new("3"); 252is($LIB->_str($LIB->_rsft($x, $y, 10)), 20, 253 qq|$LIB->_str($LIB->_rsft(\$x, \$y, 10)) = 20|); 254 255$x = $LIB->_new("256"); 256$y = $LIB->_new("4"); 257is($LIB->_str($LIB->_rsft($x, $y, 2)), 256 >> 4, 258 qq|$LIB->_str($LIB->_rsft(\$x, \$y, 2)) = 256 >> 4|); 259 260$x = $LIB->_new("6411906467305339182857313397200584952398"); 261$y = $LIB->_new("45"); 262is($LIB->_str($LIB->_rsft($x, $y, 10)), 0, 263 qq|$LIB->_str($LIB->_rsft(\$x, \$y, 10)) = 0|); 264 265# _lsft() with large bases 266 267for my $xstr ("1", "2", "3") { 268 for my $nstr ("1", "2", "3") { 269 for my $bpow (25, 50, 75) { 270 my $bstr = "1" . ("0" x $bpow); 271 my $expected = $xstr . ("0" x ($bpow * $nstr)); 272 my $xobj = $LIB->_new($xstr); 273 my $nobj = $LIB->_new($nstr); 274 my $bobj = $LIB->_new($bstr); 275 276 is($LIB->_str($LIB->_lsft($xobj, $nobj, $bobj)), $expected, 277 qq|$LIB->_str($LIB->_lsft($LIB->_new("$xstr"), | 278 . qq|$LIB->_new("$nstr"), | 279 . qq|$LIB->_new("$bstr")))|); 280 is($LIB->_str($nobj), $nstr, q|$n is unmodified|); 281 is($LIB->_str($bobj), $bstr, q|$b is unmodified|); 282 } 283 } 284} 285 286# _acmp 287 288$x = $LIB->_new("123456789"); 289$y = $LIB->_new("987654321"); 290is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp(\$x, \$y) = -1|); 291is($LIB->_acmp($y, $x), 1, qq|$LIB->_acmp(\$y, \$x) = 1|); 292is($LIB->_acmp($x, $x), 0, qq|$LIB->_acmp(\$x, \$x) = 0|); 293is($LIB->_acmp($y, $y), 0, qq|$LIB->_acmp(\$y, \$y) = 0|); 294$x = $LIB->_new("12"); 295$y = $LIB->_new("12"); 296is($LIB->_acmp($x, $y), 0, qq|$LIB->_acmp(\$x, \$y) = 0|); 297$x = $LIB->_new("21"); 298is($LIB->_acmp($x, $y), 1, qq|$LIB->_acmp(\$x, \$y) = 1|); 299is($LIB->_acmp($y, $x), -1, qq|$LIB->_acmp(\$y, \$x) = -1|); 300$x = $LIB->_new("123456789"); 301$y = $LIB->_new("1987654321"); 302is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp(\$x, \$y) = -1|); 303is($LIB->_acmp($y, $x), +1, qq|$LIB->_acmp(\$y, \$x) = +1|); 304 305$x = $LIB->_new("1234567890123456789"); 306$y = $LIB->_new("987654321012345678"); 307is($LIB->_acmp($x, $y), 1, qq|$LIB->_acmp(\$x, \$y) = 1|); 308is($LIB->_acmp($y, $x), -1, qq|$LIB->_acmp(\$y, \$x) = -1|); 309is($LIB->_acmp($x, $x), 0, qq|$LIB->_acmp(\$x, \$x) = 0|); 310is($LIB->_acmp($y, $y), 0, qq|$LIB->_acmp(\$y, \$y) = 0|); 311 312$x = $LIB->_new("1234"); 313$y = $LIB->_new("987654321012345678"); 314is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp(\$x, \$y) = -1|); 315is($LIB->_acmp($y, $x), 1, qq|$LIB->_acmp(\$y, \$x) = 1|); 316is($LIB->_acmp($x, $x), 0, qq|$LIB->_acmp(\$x, \$x) = 0|); 317is($LIB->_acmp($y, $y), 0, qq|$LIB->_acmp(\$y, \$y) = 0|); 318 319# _modinv 320 321$x = $LIB->_new("8"); 322$y = $LIB->_new("5033"); 323my ($xmod, $sign) = $LIB->_modinv($x, $y); 324is($LIB->_str($xmod), "629", # -629 % 5033 == 4404 325 qq|$LIB->_str(\$xmod) = "629"|); 326is($sign, "-", q|$sign = "-"|); 327 328# _div 329 330$x = $LIB->_new("3333"); 331$y = $LIB->_new("1111"); 332is($LIB->_str(scalar($LIB->_div($x, $y))), 3, 333 qq|$LIB->_str(scalar($LIB->_div(\$x, \$y))) = 3|); 334 335$x = $LIB->_new("33333"); 336$y = $LIB->_new("1111"); 337($x, $y) = $LIB->_div($x, $y); 338is($LIB->_str($x), 30, qq|$LIB->_str(\$x) = 30|); 339is($LIB->_str($y), 3, qq|$LIB->_str(\$y) = 3|); 340 341$x = $LIB->_new("123"); 342$y = $LIB->_new("1111"); 343($x, $y) = $LIB->_div($x, $y); 344is($LIB->_str($x), 0, qq|$LIB->_str(\$x) = 0|); 345is($LIB->_str($y), 123, qq|$LIB->_str(\$y) = 123|); 346 347# _num 348 349foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) { 350 351 $x = $LIB->_new("$_"); 352 is(ref($x), $REF, q|ref($x) = "$REF"|); 353 is($LIB->_str($x), "$_", qq|$LIB->_str(\$x) = "$_"|); 354 355 $x = $LIB->_num($x); 356 is(ref($x), "", q|ref($x) = ""|); 357 is($x, $_, qq|\$x = $_|); 358} 359 360# _sqrt 361 362$x = $LIB->_new("144"); 363is($LIB->_str($LIB->_sqrt($x)), "12", 364 qq|$LIB->_str($LIB->_sqrt(\$x)) = "12"|); 365$x = $LIB->_new("144000000000000"); 366is($LIB->_str($LIB->_sqrt($x)), "12000000", 367 qq|$LIB->_str($LIB->_sqrt(\$x)) = "12000000"|); 368 369# _root 370 371$x = $LIB->_new("81"); 372my $n = $LIB->_new("3"); # 4*4*4 = 64, 5*5*5 = 125 373is($LIB->_str($LIB->_root($x, $n)), "4", 374 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "4"|); # 4.xx => 4.0 375 376$x = $LIB->_new("81"); 377$n = $LIB->_new("4"); # 3*3*3*3 == 81 378is($LIB->_str($LIB->_root($x, $n)), "3", 379 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "3"|); 380 381# _pow (and _root) 382 383$x = $LIB->_new("0"); 384$n = $LIB->_new("3"); # 0 ** y => 0 385is($LIB->_str($LIB->_pow($x, $n)), 0, 386 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 0|); 387 388$x = $LIB->_new("3"); 389$n = $LIB->_new("0"); # x ** 0 => 1 390is($LIB->_str($LIB->_pow($x, $n)), 1, 391 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 1|); 392 393$x = $LIB->_new("1"); 394$n = $LIB->_new("3"); # 1 ** y => 1 395is($LIB->_str($LIB->_pow($x, $n)), 1, 396 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 1|); 397 398$x = $LIB->_new("5"); 399$n = $LIB->_new("1"); # x ** 1 => x 400is($LIB->_str($LIB->_pow($x, $n)), 5, 401 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 5|); 402 403$x = $LIB->_new("81"); 404$n = $LIB->_new("3"); # 81 ** 3 == 531441 405is($LIB->_str($LIB->_pow($x, $n)), 81 ** 3, 406 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 81 ** 3|); 407 408is($LIB->_str($LIB->_root($x, $n)), 81, 409 qq|$LIB->_str($LIB->_root(\$x, \$n)) = 81|); 410 411$x = $LIB->_new("81"); 412is($LIB->_str($LIB->_pow($x, $n)), 81 ** 3, 413 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = 81 ** 3|); 414is($LIB->_str($LIB->_pow($x, $n)), "150094635296999121", # 531441 ** 3 415 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = "150094635296999121"|); 416 417is($LIB->_str($LIB->_root($x, $n)), "531441", 418 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "531441"|); 419is($LIB->_str($LIB->_root($x, $n)), "81", 420 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "81"|); 421 422$x = $LIB->_new("81"); 423$n = $LIB->_new("14"); 424is($LIB->_str($LIB->_pow($x, $n)), "523347633027360537213511521", 425 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = "523347633027360537213511521"|); 426is($LIB->_str($LIB->_root($x, $n)), "81", 427 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "81"|); 428 429$x = $LIB->_new("523347633027360537213511520"); 430is($LIB->_str($LIB->_root($x, $n)), "80", 431 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "80"|); 432 433$x = $LIB->_new("523347633027360537213511522"); 434is($LIB->_str($LIB->_root($x, $n)), "81", 435 qq|$LIB->_str($LIB->_root(\$x, \$n)) = "81"|); 436 437my $res = [ qw/9 31 99 316 999 3162 9999 31622 99999/ ]; 438 439# 99 ** 2 = 9801, 999 ** 2 = 998001 etc 440 441for my $i (2 .. 9) { 442 $x = '9' x $i; 443 $x = $LIB->_new($x); 444 $n = $LIB->_new("2"); 445 my $rc = '9' x ($i-1). '8' . '0' x ($i - 1) . '1'; 446 print "# _pow( ", '9' x $i, ", 2) \n" unless 447 is($LIB->_str($LIB->_pow($x, $n)), $rc, 448 qq|$LIB->_str($LIB->_pow(\$x, \$n)) = $rc|); 449 450 SKIP: { 451 # If $i > $BASE_LEN, the test takes a really long time. 452 skip "$i > $BASE_LEN", 2 unless $i <= $BASE_LEN; 453 454 $x = '9' x $i; 455 $x = $LIB->_new($x); 456 $n = '9' x $i; 457 $n = $LIB->_new($n); 458 print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n"; 459 print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" 460 unless is($LIB->_str($LIB->_root($x, $n)), '1', 461 qq|$LIB->_str($LIB->_root(\$x, \$n)) = '1'|); 462 463 $x = '9' x $i; 464 $x = $LIB->_new($x); 465 $n = $LIB->_new("2"); 466 print "# BASE_LEN $BASE_LEN _root( ", '9' x $i, ", ", 9 x $i, ") \n" 467 unless is($LIB->_str($LIB->_root($x, $n)), $res->[$i-2], 468 qq|$LIB->_str($LIB->_root(\$x, \$n)) = $res->[$i-2]|); 469 } 470} 471 472############################################################################## 473# _fac 474 475$x = $LIB->_new("0"); 476is($LIB->_str($LIB->_fac($x)), "1", 477 qq|$LIB->_str($LIB->_fac(\$x)) = "1"|); 478 479$x = $LIB->_new("1"); 480is($LIB->_str($LIB->_fac($x)), "1", 481 qq|$LIB->_str($LIB->_fac(\$x)) = "1"|); 482 483$x = $LIB->_new("2"); 484is($LIB->_str($LIB->_fac($x)), "2", 485 qq|$LIB->_str($LIB->_fac(\$x)) = "2"|); 486 487$x = $LIB->_new("3"); 488is($LIB->_str($LIB->_fac($x)), "6", 489 qq|$LIB->_str($LIB->_fac(\$x)) = "6"|); 490 491$x = $LIB->_new("4"); 492is($LIB->_str($LIB->_fac($x)), "24", 493 qq|$LIB->_str($LIB->_fac(\$x)) = "24"|); 494 495$x = $LIB->_new("5"); 496is($LIB->_str($LIB->_fac($x)), "120", 497 qq|$LIB->_str($LIB->_fac(\$x)) = "120"|); 498 499$x = $LIB->_new("10"); 500is($LIB->_str($LIB->_fac($x)), "3628800", 501 qq|$LIB->_str($LIB->_fac(\$x)) = "3628800"|); 502 503$x = $LIB->_new("11"); 504is($LIB->_str($LIB->_fac($x)), "39916800", 505 qq|$LIB->_str($LIB->_fac(\$x)) = "39916800"|); 506 507$x = $LIB->_new("12"); 508is($LIB->_str($LIB->_fac($x)), "479001600", 509 qq|$LIB->_str($LIB->_fac(\$x)) = "479001600"|); 510 511$x = $LIB->_new("13"); 512is($LIB->_str($LIB->_fac($x)), "6227020800", 513 qq|$LIB->_str($LIB->_fac(\$x)) = "6227020800"|); 514 515# test that _fac modifies $x in place for small arguments 516 517$x = $LIB->_new("3"); 518$LIB->_fac($x); 519is($LIB->_str($x), "6", 520 qq|$LIB->_str(\$x) = "6"|); 521 522$x = $LIB->_new("13"); 523$LIB->_fac($x); 524is($LIB->_str($x), "6227020800", 525 qq|$LIB->_str(\$x) = "6227020800"|); 526 527# _inc and _dec 528 529for (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) { 530 $x = $LIB->_new("$_"); 531 $LIB->_inc($x); 532 my $expected = substr($_, 0, length($_) - 1) . '2'; 533 is($LIB->_str($x), $expected, qq|$LIB->_str(\$x) = $expected|); 534 $LIB->_dec($x); 535 is($LIB->_str($x), $_, qq|$LIB->_str(\$x) = $_|); 536} 537 538for (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) { 539 $x = $LIB->_new("$_"); 540 $LIB->_inc($x); 541 my $expected = substr($_, 0, length($_)-2) . '20'; 542 is($LIB->_str($x), $expected, qq|$LIB->_str(\$x) = $expected|); 543 $LIB->_dec($x); 544 is($LIB->_str($x), $_, qq|$LIB->_str(\$x) = $_|); 545} 546 547for (1 .. 20) { 548 my $p = "9" x $_; # = $q - 1 549 my $q = "1" . ("0" x $_); # = $p + 1 550 551 $x = $LIB->_new("$p"); 552 $LIB->_inc($x); 553 is($LIB->_str($x), $q, qq|\$x = $LIB->_new("$p"); $LIB->_inc()|); 554 555 $x = $LIB->_new("$q"); 556 $LIB->_dec($x); 557 is($LIB->_str($x), $p, qq|\$x = $LIB->_new("$q"); $LIB->_dec()|); 558} 559 560for (1 .. 20) { 561 my $p = "1" . ("0" x $_); # = $q - 1 562 my $q = "1" . ("0" x ($_ - 1)) . "1"; # = $p + 1 563 564 $x = $LIB->_new("$p"); 565 $LIB->_inc($x); 566 is($LIB->_str($x), $q, qq|\$x = $LIB->_new("$p"); $LIB->_inc()|); 567 568 $x = $LIB->_new("$q"); 569 $LIB->_dec($x); 570 is($LIB->_str($x), $p, qq|\$x = $LIB->_new("$q"); $LIB->_dec()|); 571} 572 573$x = $LIB->_new("1000"); 574$LIB->_inc($x); 575is($LIB->_str($x), "1001", qq|$LIB->_str(\$x) = "1001"|); 576$LIB->_dec($x); 577is($LIB->_str($x), "1000", qq|$LIB->_str(\$x) = "1000"|); 578 579my $BL = $LIB -> _base_len(); 580 581$x = '1' . '0' x $BL; 582$z = '1' . '0' x ($BL - 1); 583$z .= '1'; 584$x = $LIB->_new($x); 585$LIB->_inc($x); 586is($LIB->_str($x), $z, qq|$LIB->_str(\$x) = $z|); 587 588$x = '1' . '0' x $BL; 589$z = '9' x $BL; 590$x = $LIB->_new($x); 591$LIB->_dec($x); 592is($LIB->_str($x), $z, qq|$LIB->_str(\$x) = $z|); 593 594# should not happen: 595# $x = $LIB->_new("-2"); 596# $y = $LIB->_new("4"); 597# is($LIB->_acmp($x, $y), -1, qq|$LIB->_acmp($x, $y) = -1|); 598 599############################################################################### 600# _mod 601 602$x = $LIB->_new("1000"); 603$y = $LIB->_new("3"); 604is($LIB->_str(scalar($LIB->_mod($x, $y))), 1, 605 qq|$LIB->_str(scalar($LIB->_mod(\$x, \$y))) = 1|); 606 607$x = $LIB->_new("1000"); 608$y = $LIB->_new("2"); 609is($LIB->_str(scalar($LIB->_mod($x, $y))), 0, 610 qq|$LIB->_str(scalar($LIB->_mod(\$x, \$y))) = 0|); 611 612# _and, _or, _xor 613 614$x = $LIB->_new("5"); 615$y = $LIB->_new("2"); 616is($LIB->_str(scalar($LIB->_xor($x, $y))), 7, 617 qq|$LIB->_str(scalar($LIB->_xor(\$x, \$y))) = 7|); 618 619$x = $LIB->_new("5"); 620$y = $LIB->_new("2"); 621is($LIB->_str(scalar($LIB->_or($x, $y))), 7, 622 qq|$LIB->_str(scalar($LIB->_or(\$x, \$y))) = 7|); 623 624$x = $LIB->_new("5"); 625$y = $LIB->_new("3"); 626is($LIB->_str(scalar($LIB->_and($x, $y))), 1, 627 qq|$LIB->_str(scalar($LIB->_and(\$x, \$y))) = 1|); 628 629# _from_hex, _from_bin, _from_oct 630 631is($LIB->_str($LIB->_from_hex("0xFf")), 255, 632 qq|$LIB->_str($LIB->_from_hex("0xFf")) = 255|); 633is($LIB->_str($LIB->_from_bin("0b10101011")), 160+11, 634 qq|$LIB->_str($LIB->_from_bin("0b10101011")) = 160+11|); 635is($LIB->_str($LIB->_from_oct("0100")), 8*8, 636 qq|$LIB->_str($LIB->_from_oct("0100")) = 8*8|); 637is($LIB->_str($LIB->_from_oct("01000")), 8*8*8, 638 qq|$LIB->_str($LIB->_from_oct("01000")) = 8*8*8|); 639is($LIB->_str($LIB->_from_oct("010001")), 8*8*8*8+1, 640 qq|$LIB->_str($LIB->_from_oct("010001")) = 8*8*8*8+1|); 641is($LIB->_str($LIB->_from_oct("010007")), 8*8*8*8+7, 642 qq|$LIB->_str($LIB->_from_oct("010007")) = 8*8*8*8+7|); 643 644# _as_hex, _as_bin, as_oct 645 646is($LIB->_str($LIB->_from_hex($LIB->_as_hex($LIB->_new("128")))), 128, 647 qq|$LIB->_str($LIB->_from_hex($LIB->_as_hex(| 648 . qq|$LIB->_new("128")))) = 128|); 649is($LIB->_str($LIB->_from_bin($LIB->_as_bin($LIB->_new("128")))), 128, 650 qq|$LIB->_str($LIB->_from_bin($LIB->_as_bin(| 651 . qq|$LIB->_new("128")))) = 128|); 652is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("128")))), 128, 653 qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| 654 . qq|$LIB->_new("128")))) = 128|); 655 656is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("123456")))), 657 123456, 658 qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct| 659 . qq|($LIB->_new("123456")))) = 123456|); 660is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("123456789")))), 661 "123456789", 662 qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| 663 . qq|$LIB->_new("123456789")))) = "123456789"|); 664is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("1234567890123")))), 665 "1234567890123", 666 qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| 667 . qq|$LIB->_new("1234567890123")))) = "1234567890123"|); 668 669my $long = "123456789012345678901234567890"; 670is($LIB->_str($LIB->_from_hex($LIB->_as_hex($LIB->_new($long)))), $long, 671 qq|$LIB->_str($LIB->_from_hex($LIB->_as_hex(| 672 . qq|$LIB->_new("$long")))) = "$long"|); 673is($LIB->_str($LIB->_from_bin($LIB->_as_bin($LIB->_new($long)))), $long, 674 qq|$LIB->_str($LIB->_from_bin($LIB->_as_bin(| 675 . qq|$LIB->_new("$long")))) = "$long"|); 676is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new($long)))), $long, 677 qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| 678 . qq|$LIB->_new("$long")))) = "$long"|); 679 680is($LIB->_str($LIB->_from_hex($LIB->_as_hex($LIB->_new("0")))), 0, 681 qq|$LIB->_str($LIB->_from_hex($LIB->_as_hex(| 682 . qq|$LIB->_new("0")))) = 0|); 683is($LIB->_str($LIB->_from_bin($LIB->_as_bin($LIB->_new("0")))), 0, 684 qq|$LIB->_str($LIB->_from_bin($LIB->_as_bin(| 685 . qq|$LIB->_new("0")))) = 0|); 686is($LIB->_str($LIB->_from_oct($LIB->_as_oct($LIB->_new("0")))), 0, 687 qq|$LIB->_str($LIB->_from_oct($LIB->_as_oct(| 688 . qq|$LIB->_new("0")))) = 0|); 689 690is($LIB->_as_hex($LIB->_new("0")), "0x0", 691 qq|$LIB->_as_hex($LIB->_new("0")) = "0x0"|); 692is($LIB->_as_bin($LIB->_new("0")), "0b0", 693 qq|$LIB->_as_bin($LIB->_new("0")) = "0b0"|); 694is($LIB->_as_oct($LIB->_new("0")), "00", 695 qq|$LIB->_as_oct($LIB->_new("0")) = "00"|); 696 697is($LIB->_as_hex($LIB->_new("12")), "0xc", 698 qq|$LIB->_as_hex($LIB->_new("12")) = "0xc"|); 699is($LIB->_as_bin($LIB->_new("12")), "0b1100", 700 qq|$LIB->_as_bin($LIB->_new("12")) = "0b1100"|); 701is($LIB->_as_oct($LIB->_new("64")), "0100", 702 qq|$LIB->_as_oct($LIB->_new("64")) = "0100"|); 703 704# _1ex 705 706is($LIB->_str($LIB->_1ex(0)), "1", 707 qq|$LIB->_str($LIB->_1ex(0)) = "1"|); 708is($LIB->_str($LIB->_1ex(1)), "10", 709 qq|$LIB->_str($LIB->_1ex(1)) = "10"|); 710is($LIB->_str($LIB->_1ex(2)), "100", 711 qq|$LIB->_str($LIB->_1ex(2)) = "100"|); 712is($LIB->_str($LIB->_1ex(12)), "1000000000000", 713 qq|$LIB->_str($LIB->_1ex(12)) = "1000000000000"|); 714is($LIB->_str($LIB->_1ex(16)), "10000000000000000", 715 qq|$LIB->_str($LIB->_1ex(16)) = "10000000000000000"|); 716 717# _check 718 719$x = $LIB->_new("123456789"); 720is($LIB->_check($x), 0, 721 qq|$LIB->_check(\$x) = 0|); 722is($LIB->_check(123), "123 is not a reference", 723 qq|$LIB->_check(123) = "123 is not a reference"|); 724 725############################################################################### 726# __strip_zeros 727 728{ 729 no strict 'refs'; 730 731 # correct empty arrays 732 $x = &{$LIB."::__strip_zeros"}([]); 733 is(@$x, 1, q|@$x = 1|); 734 is($x->[0], 0, q|$x->[0] = 0|); 735 736 # don't strip single elements 737 $x = &{$LIB."::__strip_zeros"}([0]); 738 is(@$x, 1, q|@$x = 1|); 739 is($x->[0], 0, q|$x->[0] = 0|); 740 $x = &{$LIB."::__strip_zeros"}([1]); 741 is(@$x, 1, q|@$x = 1|); 742 is($x->[0], 1, q|$x->[0] = 1|); 743 744 # don't strip non-zero elements 745 $x = &{$LIB."::__strip_zeros"}([0, 1]); 746 is(@$x, 2, q|@$x = 2|); 747 is($x->[0], 0, q|$x->[0] = 0|); 748 is($x->[1], 1, q|$x->[1] = 1|); 749 $x = &{$LIB."::__strip_zeros"}([0, 1, 2]); 750 is(@$x, 3, q|@$x = 3|); 751 is($x->[0], 0, q|$x->[0] = 0|); 752 is($x->[1], 1, q|$x->[1] = 1|); 753 is($x->[2], 2, q|$x->[2] = 2|); 754 755 # but strip leading zeros 756 $x = &{$LIB."::__strip_zeros"}([0, 1, 2, 0]); 757 is(@$x, 3, q|@$x = 3|); 758 is($x->[0], 0, q|$x->[0] = 0|); 759 is($x->[1], 1, q|$x->[1] = 1|); 760 is($x->[2], 2, q|$x->[2] = 2|); 761 762 $x = &{$LIB."::__strip_zeros"}([0, 1, 2, 0, 0]); 763 is(@$x, 3, q|@$x = 3|); 764 is($x->[0], 0, q|$x->[0] = 0|); 765 is($x->[1], 1, q|$x->[1] = 1|); 766 is($x->[2], 2, q|$x->[2] = 2|); 767 768 $x = &{$LIB."::__strip_zeros"}([0, 1, 2, 0, 0, 0]); 769 is(@$x, 3, q|@$x = 3|); 770 is($x->[0], 0, q|$x->[0] = 0|); 771 is($x->[1], 1, q|$x->[1] = 1|); 772 is($x->[2], 2, q|$x->[2] = 2|); 773 774 # collapse multiple zeros 775 $x = &{$LIB."::__strip_zeros"}([0, 0, 0, 0]); 776 is(@$x, 1, q|@$x = 1|); 777 is($x->[0], 0, q|$x->[0] = 0|); 778} 779