1 #include this file into another for subclass testing
3 my $version = ${"$class\::VERSION"};
5 ##############################################################################
6 # for testing inheritance of _swap
11 #use Math::BigInt lib => 'BitVect'; # for testing
13 @ISA = (qw/Math::BigInt/);
16 # customized overload for sub, since original does not use swap there
17 '-' => sub { my @a = ref($_[0])->_swap(@_);
22 # a fake _swap, which reverses the params
23 my $self = shift; # for override in subclass
26 my $c = ref ($_[0] ) || 'Math::Foo';
27 return ( $_[0]->copy(), $_[1] );
31 return ( Math::Foo->new($_[1]), $_[0] );
35 ##############################################################################
38 my $CALC = $class->_core_lib(); ok ($CALC,'Math::BigInt::Calc');
40 my ($f,$z,$a,$exp,@a,$m,$e,$round_mode);
45 next if /^#/; # skip comments
53 $round_mode =~ s/^\$/$class\->/;
54 # print "$round_mode\n";
58 @args = split(/:/,$_,99);
60 $try = "\$x = $class->new(\"$args[0]\");";
62 $try = "\$x = $class->bnorm(\"$args[0]\");";
63 } elsif ($f eq "is_zero") {
64 $try .= '$x->is_zero();';
65 } elsif ($f eq "is_one") {
66 $try .= '$x->is_one();';
67 } elsif ($f eq "is_odd") {
68 $try .= '$x->is_odd();';
69 } elsif ($f eq "is_even") {
70 $try .= '$x->is_even();';
71 } elsif ($f eq "is_negative") {
72 $try .= '$x->is_negative();';
73 } elsif ($f eq "is_positive") {
74 $try .= '$x->is_positive();';
75 } elsif ($f eq "as_hex") {
76 $try .= '$x->as_hex();';
77 } elsif ($f eq "as_bin") {
78 $try .= '$x->as_bin();';
79 } elsif ($f eq "is_inf") {
80 $try .= "\$x->is_inf('$args[1]');";
81 } elsif ($f eq "binf") {
82 $try .= "\$x->binf('$args[1]');";
83 } elsif ($f eq "bone") {
84 $try .= "\$x->bone('$args[1]');";
85 } elsif ($f eq "bnan") {
86 $try .= "\$x->bnan();";
87 } elsif ($f eq "bfloor") {
88 $try .= '$x->bfloor();';
89 } elsif ($f eq "bceil") {
90 $try .= '$x->bceil();';
91 } elsif ($f eq "bsstr") {
92 $try .= '$x->bsstr();';
93 } elsif ($f eq "bneg") {
94 $try .= '$x->bneg();';
95 } elsif ($f eq "babs") {
96 $try .= '$x->babs();';
97 } elsif ($f eq "binc") {
99 } elsif ($f eq "bdec") {
101 }elsif ($f eq "bnot") {
103 }elsif ($f eq "bsqrt") {
104 $try .= '$x->bsqrt();';
105 }elsif ($f eq "length") {
106 $try .= '$x->length();';
107 }elsif ($f eq "exponent"){
108 # ->bstr() to see if an object is returned
109 $try .= '$x = $x->exponent()->bstr();';
110 }elsif ($f eq "mantissa"){
111 # ->bstr() to see if an object is returned
112 $try .= '$x = $x->mantissa()->bstr();';
113 }elsif ($f eq "parts"){
114 $try .= '($m,$e) = $x->parts();';
115 # ->bstr() to see if an object is returned
116 $try .= '$m = $m->bstr(); $m = "NaN" if !defined $m;';
117 $try .= '$e = $e->bstr(); $e = "NaN" if !defined $e;';
120 $try .= "\$y = $class->new('$args[1]');";
122 $try .= '$x <=> $y;';
123 }elsif ($f eq "bround") {
124 $try .= "$round_mode; \$x->bround(\$y);";
125 }elsif ($f eq "bacmp"){
126 $try .= '$x->bacmp($y);';
127 }elsif ($f eq "badd"){
129 }elsif ($f eq "bsub"){
131 }elsif ($f eq "bmul"){
133 }elsif ($f eq "bdiv"){
135 }elsif ($f eq "bdiv-list"){
136 $try .= 'join (",",$x->bdiv($y));';
137 }elsif ($f eq "bmod"){
139 }elsif ($f eq "bgcd")
141 if (defined $args[2])
143 $try .= " \$z = $class->new(\"$args[2]\"); ";
145 $try .= "$class\::bgcd(\$x, \$y";
146 $try .= ", \$z" if (defined $args[2]);
151 if (defined $args[2])
153 $try .= " \$z = $class->new(\"$args[2]\"); ";
155 $try .= "$class\::blcm(\$x, \$y";
156 $try .= ", \$z" if (defined $args[2]);
158 }elsif ($f eq "blsft"){
159 if (defined $args[2])
161 $try .= "\$x->blsft(\$y,$args[2]);";
165 $try .= "\$x << \$y;";
167 }elsif ($f eq "brsft"){
168 if (defined $args[2])
170 $try .= "\$x->brsft(\$y,$args[2]);";
174 $try .= "\$x >> \$y;";
176 }elsif ($f eq "band"){
177 $try .= "\$x & \$y;";
178 }elsif ($f eq "bior"){
179 $try .= "\$x | \$y;";
180 }elsif ($f eq "bxor"){
181 $try .= "\$x ^ \$y;";
182 }elsif ($f eq "bpow"){
183 $try .= "\$x ** \$y;";
184 }elsif ($f eq "digit"){
185 $try = "\$x = $class->new(\"$args[0]\"); \$x->digit($args[1]);";
186 } else { warn "Unknown op '$f'"; }
188 # print "trying $try\n";
190 $ans =~ s/^[+]([0-9])/$1/; # remove leading '+'
197 # print "try: $try ans: $ans1 $ans\n";
198 print "# Tried: '$try'\n" if !ok ($ans1, $ans);
200 # check internal state of number objects
201 is_valid($ans1,$f) if ref $ans1;
203 } # endwhile data tests
208 for (my $i = 1; $i < 10; $i++)
212 ok "@a", "1 2 3 4 5 6 7 8 9";
214 # test whether self-multiplication works correctly (result is 2**64)
215 $try = "\$x = $class->new('4294967296');";
216 $try .= '$a = $x->bmul($x);';
218 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(2) ** 64);
220 $try = "\$x = $class->new(10);";
221 $try .= '$a = $x->bpow($x);';
223 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(10) ** 10);
225 # test whether op destroys args or not (should better not)
251 $x = $class->new(-5); $y = -$x;
254 $x = $class->new(-5); $y = abs($x);
257 # check whether overloading cmp works
258 $try = "\$x = $class->new(0);";
260 $try .= "'false' if \$x ne \$y;";
262 print "# For '$try'\n" if (!ok "$ans" , "false" );
264 # we cant test for working cmpt with other objects here, we would need a dummy
265 # object with stringify overload for this. see Math::String tests as example
267 ###############################################################################
269 $try = "\$x = $class->new(1); \$x += 9;";
270 $try .= "'ok' if \$x == 10;";
272 print "# For '$try'\n" if (!ok "$ans" , "ok" );
274 $try = "\$x = $class->new(1); \$x -= 9;";
275 $try .= "'ok' if \$x == -8;";
277 print "# For '$try'\n" if (!ok "$ans" , "ok" );
279 $try = "\$x = $class->new(1); \$x *= 9;";
280 $try .= "'ok' if \$x == 9;";
282 print "# For '$try'\n" if (!ok "$ans" , "ok" );
284 $try = "\$x = $class->new(10); \$x /= 2;";
285 $try .= "'ok' if \$x == 5;";
287 print "# For '$try'\n" if (!ok "$ans" , "ok" );
289 ###############################################################################
290 # check reversed order of arguments
291 $try = "\$x = $class->new(10); \$x = 2 ** \$x;";
292 $try .= "'ok' if \$x == 1024;"; $ans = eval $try;
293 print "# For '$try'\n" if (!ok "$ans" , "ok" );
295 $try = "\$x = $class->new(10); \$x = 2 * \$x;";
296 $try .= "'ok' if \$x == 20;"; $ans = eval $try;
297 print "# For '$try'\n" if (!ok "$ans" , "ok" );
299 $try = "\$x = $class->new(10); \$x = 2 + \$x;";
300 $try .= "'ok' if \$x == 12;"; $ans = eval $try;
301 print "# For '$try'\n" if (!ok "$ans" , "ok" );
303 $try = "\$x = $class\->new(10); \$x = 2 - \$x;";
304 $try .= "'ok' if \$x == -8;"; $ans = eval $try;
305 print "# For '$try'\n" if (!ok "$ans" , "ok" );
307 $try = "\$x = $class\->new(10); \$x = 20 / \$x;";
308 $try .= "'ok' if \$x == 2;"; $ans = eval $try;
309 print "# For '$try'\n" if (!ok "$ans" , "ok" );
311 ###############################################################################
312 # check badd(4,5) form
314 $try = "\$x = $class\->badd(4,5);";
315 $try .= "'ok' if \$x == 9;";
317 print "# For '$try'\n" if (!ok "$ans" , "ok" );
319 ###############################################################################
320 # check undefs: NOT DONE YET
322 ###############################################################################
325 $x = Math::BigInt->new(1); if ($x) { ok (1,1); } else { ok($x,'to be true') }
326 $x = Math::BigInt->new(0); if (!$x) { ok (1,1); } else { ok($x,'to be false') }
328 ###############################################################################
331 @args = Math::BigInt::objectify(2,4,5);
332 ok (scalar @args,3); # $class, 4, 5
333 ok ($args[0],$class);
337 @args = Math::BigInt::objectify(0,4,5);
338 ok (scalar @args,3); # $class, 4, 5
339 ok ($args[0],$class);
343 @args = Math::BigInt::objectify(2,4,5);
344 ok (scalar @args,3); # $class, 4, 5
345 ok ($args[0],$class);
349 @args = Math::BigInt::objectify(2,4,5,6,7);
350 ok (scalar @args,5); # $class, 4, 5, 6, 7
351 ok ($args[0],$class);
352 ok ($args[1],4); ok (ref($args[1]),$args[0]);
353 ok ($args[2],5); ok (ref($args[2]),$args[0]);
354 ok ($args[3],6); ok (ref($args[3]),'');
355 ok ($args[4],7); ok (ref($args[4]),'');
357 @args = Math::BigInt::objectify(2,$class,4,5,6,7);
358 ok (scalar @args,5); # $class, 4, 5, 6, 7
359 ok ($args[0],$class);
360 ok ($args[1],4); ok (ref($args[1]),$args[0]);
361 ok ($args[2],5); ok (ref($args[2]),$args[0]);
362 ok ($args[3],6); ok (ref($args[3]),'');
363 ok ($args[4],7); ok (ref($args[4]),'');
365 ###############################################################################
366 # test for floating-point input (other tests in bnorm() below)
368 $z = 1050000000000000; # may be int on systems with 64bit?
369 $x = $class->new($z); ok ($x->bsstr(),'105e+13'); # not 1.05e+15
370 $z = 1e+129; # definitely a float (may fail on UTS)
371 # don't compare to $z, since some Perl versions stringify $z into something
372 # like '1.e+129' or something equally ugly
373 $x = $class->new($z); ok ($x->bsstr(),'1e+129');
375 ###############################################################################
376 # prime number tests, also test for **= and length()
377 # found on: http://www.utm.edu/research/primes/notes/by_year.html
380 $x = $class->new(2); $x **= 148; $x++; $x = $x / 17;
381 ok ($x,"20988936657440586486151264256610222593863921");
382 ok ($x->length(),length "20988936657440586486151264256610222593863921");
385 $x = $class->new(2); $x **= 127; $x--;
386 ok ($x,"170141183460469231731687303715884105727");
388 $x = $class->new('215960156869840440586892398248');
389 ($x,$y) = $x->length();
390 ok ($x,30); ok ($y,0);
392 $x = $class->new('1_000_000_000_000');
393 ($x,$y) = $x->length();
394 ok ($x,13); ok ($y,0);
396 # I am afraid the following is not yet possible due to slowness
397 # Also, testing for 2 meg output is a bit hard ;)
398 #$x = $class->new(2); $x **= 6972593; $x--;
400 # 593573509*2^332162+1 has exactly 1,000,000 digits
401 # takes about 24 mins on 300 Mhz, so cannot be done yet ;)
402 #$x = $class->new(2); $x **= 332162; $x *= "593573509"; $x++;
403 #ok ($x->length(),1_000_000);
405 ###############################################################################
406 # inheritance and overriding of _swap
408 $x = Math::Foo->new(5);
409 $x = $x - 8; # 8 - 5 instead of 5-8
411 ok (ref($x),'Math::Foo');
413 $x = Math::Foo->new(5);
414 $x = 8 - $x; # 5 - 8 instead of 8 - 5
416 ok (ref($x),'Math::Foo');
418 ###############################################################################
419 # Test whether +inf eq inf
420 # This tried to test whether BigInt inf equals Perl inf. Unfortunately, Perl
421 # hasn't (before 5.7.3 at least) a consistent way to say inf, and some things
422 # like 1e100000 crash on some platforms. So simple test for the string 'inf'
423 $x = $class->new('+inf'); ok ($x,'inf');
425 ###############################################################################
426 ###############################################################################
427 # the followin tests only make sense with Math::BigInt::Calc
429 exit if $CALC ne 'Math::BigInt::Calc'; # for Pari et al.
431 ###############################################################################
432 # check proper length of internal arrays
434 my $bl = Math::BigInt::Calc::_base_len();
435 my $BASE = '9' x $bl;
439 $x = $class->new($MAX); is_valid($x); # f.i. 9999
440 $x += 1; ok ($x,$BASE); is_valid($x); # 10000
441 $x -= 1; ok ($x,$MAX); is_valid($x); # 9999 again
443 ###############################################################################
446 $x = $class->new($BASE-1); ok ($x->numify(),$BASE-1);
447 $x = $class->new(-($BASE-1)); ok ($x->numify(),-($BASE-1));
448 $x = $class->new($BASE); ok ($x->numify(),$BASE);
449 $x = $class->new(-$BASE); ok ($x->numify(),-$BASE);
450 $x = $class->new( -($BASE*$BASE*1+$BASE*1+1) );
451 ok($x->numify(),-($BASE*$BASE*1+$BASE*1+1));
453 ###############################################################################
454 # test bug in _digits with length($c[-1]) where $c[-1] was "00001" instead of 1
456 $x = Math::BigInt->new(99998); $x++; $x++; $x++; $x++;
457 if ($x > 100000) { ok (1,1) } else { ok ("$x < 100000","$x > 100000"); }
459 $x = Math::BigInt->new(100003); $x++;
460 $y = Math::BigInt->new(1000000);
461 if ($x < 1000000) { ok (1,1) } else { ok ("$x > 1000000","$x < 1000000"); }
463 ###############################################################################
464 # bug in sub where number with at least 6 trailing zeros after any op failed
466 $x = Math::BigInt->new(123456); $z = Math::BigInt->new(10000); $z *= 10;
471 ###############################################################################
472 # bug in shortcut in mul()
474 # construct a number with a zero-hole of BASE_LEN
475 $x = '1' x $bl . '0' x $bl . '1' x $bl . '0' x $bl;
478 $x = Math::BigInt->new($x)->bmul($y);
479 # result is 123..$bl . $bl x (3*bl-1) . $bl...321 . '0' x $bl
481 for (my $i = 1; $i <= $bl; $i++)
483 $y .= $i; $d = $i.$d;
486 $y .= $bl x (3*$bl-1) . $d . '0' x $bl;
489 ###############################################################################
490 # bug with rest "-0" in div, causing further div()s to fail
492 $x = Math::BigInt->new('-322056000'); ($x,$y) = $x->bdiv('-12882240');
494 ok ($y,'0','not -0'); # not '-0'
497 ### all tests done ############################################################
501 ###############################################################################
502 # Perl 5.005 does not like ok ($x,undef)
508 ok (1,1) and return if !defined $x;
512 ###############################################################################
513 # sub to check validity of a BigInt internally, to ensure that no op leaves a
514 # number object in an invalid state (f.i. "-0")
522 $e = 'Not a reference to Math::BigInt' if !ref($x);
525 $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'"
526 if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/;
528 $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0;
529 $e = $CALC->_check($x->{value}) if $e eq '0';
531 # test done, see if error did crop up
532 ok (1,1), return if ($e eq '0');
534 ok (1,$e." op '$f'");
579 -123456789:+987654321:-1
580 +123456789:-987654321:-1
581 +987654321:+123456789:1
582 -987654321:+123456789:1
614 0b1000000000000000000000000000000:1073741824
625 0x1_2_3_4_56_78:305419896
655 -123456789:-123456789
672 # floating point input
707 # it must be exactly /^[+-]inf$/
714 +1:+48:+281474976710656
717 +12345:4:10:123450000
723 1234567890123:12:10:1234567890123000000000000
728 +281474976710656:+48:+1
739 1230000000000:10:10:123
740 09876123456789067890:12:10:9876123
741 1234561234567890123:13:10:123456
755 +123456789:-123456789
756 -123456789:+123456789
764 +123456789:+123456789
765 -123456789:+123456789
790 -123456789:+987654321:-1
791 +123456789:-987654321:1
792 -987654321:+123456789:-1
851 +9999999:+1:+10000000
852 +99999999:+1:+100000000
853 +999999999:+1:+1000000000
854 +9999999999:+1:+10000000000
855 +99999999999:+1:+100000000000
862 +10000000:-1:+9999999
863 +100000000:-1:+99999999
864 +1000000000:-1:+999999999
865 +10000000000:-1:+9999999999
866 +123456789:+987654321:+1111111110
867 -123456789:+987654321:+864197532
868 -123456789:-987654321:-1111111110
869 +123456789:-987654321:-864197532
894 +99999999:+1:+99999998
895 +999999999:+1:+999999998
896 +9999999999:+1:+9999999998
897 +99999999999:+1:+99999999998
904 +10000000:-1:+10000001
905 +100000000:-1:+100000001
906 +1000000000:-1:+1000000001
907 +10000000000:-1:+10000000001
908 +123456789:+987654321:-864197532
909 -123456789:+987654321:-1111111110
910 -123456789:-987654321:+864197532
911 +123456789:-987654321:+1111111110
929 +123456789123456789:+0:+0
930 +0:+123456789123456789:+0
940 +10101:+10101:+102030201
941 +1001001:+1001001:+1002003002001
942 +100010001:+100010001:+10002000300020001
943 +10000100001:+10000100001:+100002000030000200001
944 +11111111111:+9:+99999999999
945 +22222222222:+9:+199999999998
946 +33333333333:+9:+299999999997
947 +44444444444:+9:+399999999996
948 +55555555555:+9:+499999999995
949 +66666666666:+9:+599999999994
950 +77777777777:+9:+699999999993
951 +88888888888:+9:+799999999992
952 +99999999999:+9:+899999999991
954 +12345:+12345:+152399025
955 +99999:+11111:+1111088889
957 99999:100000:9999900000
958 999999:1000000:999999000000
959 9999999:10000000:99999990000000
960 99999999:100000000:9999999900000000
961 999999999:1000000000:999999999000000000
962 9999999999:10000000000:99999999990000000000
963 99999999999:100000000000:9999999999900000000000
964 999999999999:1000000000000:999999999999000000000000
965 9999999999999:10000000000000:99999999999990000000000000
966 99999999999999:100000000000000:9999999999999900000000000000
967 999999999999999:1000000000000000:999999999999999000000000000000
968 9999999999999999:10000000000000000:99999999999999990000000000000000
969 99999999999999999:100000000000000000:9999999999999999900000000000000000
970 999999999999999999:1000000000000000000:999999999999999999000000000000000000
971 9999999999999999999:10000000000000000000:99999999999999999990000000000000000000
979 # inf handling and general remainder
985 # see table in documentation in MBI
1004 # exceptions to reminder rule
1013 # inf handling (see table in doc)
1048 +1000000000:+9:+111111111
1049 +2000000000:+9:+222222222
1050 +3000000000:+9:+333333333
1051 +4000000000:+9:+444444444
1052 +5000000000:+9:+555555555
1053 +6000000000:+9:+666666666
1054 +7000000000:+9:+777777777
1055 +8000000000:+9:+888888888
1056 +9000000000:+9:+1000000000
1057 +35500000:+113:+314159
1058 +71000000:+226:+314159
1059 +106500000:+339:+314159
1060 +1000000000:+3:+333333333
1065 +999999999999:+9:+111111111111
1066 +999999999999:+99:+10101010101
1067 +999999999999:+999:+1001001001
1068 +999999999999:+9999:+100010001
1069 +999999999999999:+99999:+10000100001
1070 +1111088889:+99999:+11111
1085 # bug in Calc with '99999' vs $BASE-1
1086 10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576
1088 # inf handling, see table in doc
1107 # exceptions to reminder rule
1143 +999999999999:+99:+0
1144 +999999999999:+999:+0
1145 +999999999999:+9999:+0
1146 +999999999999999:+99999:+0
1191 +281474976710656:+0:+0
1192 +281474976710656:+1:+0
1193 +281474976710656:+281474976710656:+281474976710656
1206 +281474976710656:+0:+281474976710656
1207 +281474976710656:+1:+281474976710657
1208 +281474976710656:+281474976710656:+281474976710656
1220 +281474976710656:+0:+281474976710656
1221 +281474976710656:+1:+281474976710657
1222 +281474976710656:+281474976710656:+0
1234 +281474976710656:-281474976710657
1314 -inf:1234500012:-inf
1315 +inf:-12345000123:inf
1316 -inf:-12345000123:-inf
1317 # 1 ** -x => 1 / (1 ** x)
1337 10:20:100000000000000000000
1338 123456:2:15241383936
1345 10000000000000000:17
1347 215960156869840440586892398248:30
1356 4000000000000:2000000
1362 $round_mode('trunc')
1372 +10123456789:5:+10123000000
1373 -10123456789:5:-10123000000
1374 +10123456789:9:+10123456700
1375 -10123456789:9:-10123456700
1376 +101234500:6:+101234000
1377 -101234500:6:-101234000
1378 #+101234500:-4:+101234000
1379 #-101234500:-4:-101234000
1381 +20123456789:5:+20123000000
1382 -20123456789:5:-20123000000
1383 +20123456789:9:+20123456800
1384 -20123456789:9:-20123456800
1385 +201234500:6:+201234000
1386 -201234500:6:-201234000
1387 #+201234500:-4:+201234000
1388 #-201234500:-4:-201234000
1389 +12345000:4:12340000
1390 -12345000:4:-12340000
1392 +30123456789:5:+30123000000
1393 -30123456789:5:-30123000000
1394 +30123456789:9:+30123456800
1395 -30123456789:9:-30123456800
1396 +301234500:6:+301235000
1397 -301234500:6:-301234000
1398 #+301234500:-4:+301235000
1399 #-301234500:-4:-301234000
1400 +12345000:4:12350000
1401 -12345000:4:-12340000
1403 +40123456789:5:+40123000000
1404 -40123456789:5:-40123000000
1405 +40123456789:9:+40123456800
1406 -40123456789:9:-40123456800
1407 +401234500:6:+401234000
1408 +401234500:6:+401234000
1409 #-401234500:-4:-401235000
1410 #-401234500:-4:-401235000
1411 +12345000:4:12340000
1412 -12345000:4:-12350000
1414 +50123456789:5:+50123000000
1415 -50123456789:5:-50123000000
1416 +50123456789:9:+50123456800
1417 -50123456789:9:-50123456800
1418 +501234500:6:+501235000
1419 -501234500:6:-501235000
1420 #+501234500:-4:+501235000
1421 #-501234500:-4:-501235000
1422 +12345000:4:12350000
1423 -12345000:4:-12350000
1425 +60123456789:5:+60123000000
1426 -60123456789:5:-60123000000
1427 +60123456789:9:+60123456800
1428 -60123456789:9:-60123456800
1429 +601234500:6:+601234000
1430 -601234500:6:-601234000
1431 #+601234500:-4:+601234000
1432 #-601234500:-4:-601234000
1439 +12345000:4:12340000
1440 -12345000:4:-12340000
1458 # floor and ceil tests are pretty pointless in integer space...but play safe
1485 0x123456789123456789:0x123456789123456789
1495 0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101