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]\");";
64 } elsif ($f =~ /^is_(zero|one|odd|even|negative|positive|nan)$/) {
66 } elsif ($f eq "as_hex") {
67 $try .= '$x->as_hex();';
68 } elsif ($f eq "as_bin") {
69 $try .= '$x->as_bin();';
70 } elsif ($f eq "is_inf") {
71 $try .= "\$x->is_inf('$args[1]');";
72 } elsif ($f eq "binf") {
73 $try .= "\$x->binf('$args[1]');";
74 } elsif ($f eq "bone") {
75 $try .= "\$x->bone('$args[1]');";
77 } elsif ($f =~ /^b(nan|floor|ceil|sstr|neg|abs|inc|dec|not|sqrt)$/) {
79 }elsif ($f eq "length") {
80 $try .= '$x->length();';
81 }elsif ($f eq "exponent"){
82 # ->bstr() to see if an object is returned
83 $try .= '$x = $x->exponent()->bstr();';
84 }elsif ($f eq "mantissa"){
85 # ->bstr() to see if an object is returned
86 $try .= '$x = $x->mantissa()->bstr();';
87 }elsif ($f eq "parts"){
88 $try .= '($m,$e) = $x->parts();';
89 # ->bstr() to see if an object is returned
90 $try .= '$m = $m->bstr(); $m = "NaN" if !defined $m;';
91 $try .= '$e = $e->bstr(); $e = "NaN" if !defined $e;';
94 $try .= "\$y = $class->new('$args[1]');";
97 }elsif ($f eq "bround") {
98 $try .= "$round_mode; \$x->bround(\$y);";
99 }elsif ($f eq "bacmp"){
100 $try .= '$x->bacmp($y);';
101 }elsif ($f eq "badd"){
103 }elsif ($f eq "bsub"){
105 }elsif ($f eq "bmul"){
107 }elsif ($f eq "bdiv"){
109 }elsif ($f eq "bdiv-list"){
110 $try .= 'join (",",$x->bdiv($y));';
112 }elsif ($f =~ /^.=$/){
113 $try .= "\$x $f \$y;";
115 }elsif ($f =~ /^.$/){
116 $try .= "\$x $f \$y;";
117 }elsif ($f eq "bmod"){
119 }elsif ($f eq "bgcd")
121 if (defined $args[2])
123 $try .= " \$z = $class->new(\"$args[2]\"); ";
125 $try .= "$class\::bgcd(\$x, \$y";
126 $try .= ", \$z" if (defined $args[2]);
131 if (defined $args[2])
133 $try .= " \$z = $class->new(\"$args[2]\"); ";
135 $try .= "$class\::blcm(\$x, \$y";
136 $try .= ", \$z" if (defined $args[2]);
138 }elsif ($f eq "blsft"){
139 if (defined $args[2])
141 $try .= "\$x->blsft(\$y,$args[2]);";
145 $try .= "\$x << \$y;";
147 }elsif ($f eq "brsft"){
148 if (defined $args[2])
150 $try .= "\$x->brsft(\$y,$args[2]);";
154 $try .= "\$x >> \$y;";
156 }elsif ($f eq "band"){
157 $try .= "\$x & \$y;";
158 }elsif ($f eq "bior"){
159 $try .= "\$x | \$y;";
160 }elsif ($f eq "bxor"){
161 $try .= "\$x ^ \$y;";
162 }elsif ($f eq "bpow"){
163 $try .= "\$x ** \$y;";
164 }elsif ($f eq "digit"){
165 $try = "\$x = $class->new(\"$args[0]\"); \$x->digit($args[1]);";
166 } else { warn "Unknown op '$f'"; }
168 # print "trying $try\n";
170 $ans =~ s/^[+]([0-9])/$1/; # remove leading '+'
177 # print "try: $try ans: $ans1 $ans\n";
178 print "# Tried: '$try'\n" if !ok ($ans1, $ans);
180 # check internal state of number objects
181 is_valid($ans1,$f) if ref $ans1;
183 } # endwhile data tests
188 for (my $i = 1; $i < 10; $i++)
192 ok "@a", "1 2 3 4 5 6 7 8 9";
194 # test whether self-multiplication works correctly (result is 2**64)
195 $try = "\$x = $class->new('4294967296');";
196 $try .= '$a = $x->bmul($x);';
198 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(2) ** 64);
200 $try = "\$x = $class->new(10);";
201 $try .= '$a = $x->bpow($x);';
203 print "# Tried: '$try'\n" if !ok ($ans1, $class->new(10) ** 10);
205 # test whether op destroys args or not (should better not)
231 $x = $class->new(-5); $y = -$x;
234 $x = $class->new(-5); $y = abs($x);
237 # check whether overloading cmp works
238 $try = "\$x = $class->new(0);";
240 $try .= "'false' if \$x ne \$y;";
242 print "# For '$try'\n" if (!ok "$ans" , "false" );
244 # we cant test for working cmpt with other objects here, we would need a dummy
245 # object with stringify overload for this. see Math::String tests as example
247 ###############################################################################
248 # check reversed order of arguments
250 $try = "\$x = $class->new(10); \$x = 2 ** \$x;";
251 $try .= "'ok' if \$x == 1024;"; $ans = eval $try;
252 print "# For '$try'\n" if (!ok "$ans" , "ok" );
254 $try = "\$x = $class->new(10); \$x = 2 * \$x;";
255 $try .= "'ok' if \$x == 20;"; $ans = eval $try;
256 print "# For '$try'\n" if (!ok "$ans" , "ok" );
258 $try = "\$x = $class->new(10); \$x = 2 + \$x;";
259 $try .= "'ok' if \$x == 12;"; $ans = eval $try;
260 print "# For '$try'\n" if (!ok "$ans" , "ok" );
262 $try = "\$x = $class\->new(10); \$x = 2 - \$x;";
263 $try .= "'ok' if \$x == -8;"; $ans = eval $try;
264 print "# For '$try'\n" if (!ok "$ans" , "ok" );
266 $try = "\$x = $class\->new(10); \$x = 20 / \$x;";
267 $try .= "'ok' if \$x == 2;"; $ans = eval $try;
268 print "# For '$try'\n" if (!ok "$ans" , "ok" );
270 $try = "\$x = $class\->new(3); \$x = 20 % \$x;";
271 $try .= "'ok' if \$x == 2;"; $ans = eval $try;
272 print "# For '$try'\n" if (!ok "$ans" , "ok" );
274 $try = "\$x = $class\->new(7); \$x = 20 & \$x;";
275 $try .= "'ok' if \$x == 4;"; $ans = eval $try;
276 print "# For '$try'\n" if (!ok "$ans" , "ok" );
278 $try = "\$x = $class\->new(7); \$x = 0x20 | \$x;";
279 $try .= "'ok' if \$x == 0x27;"; $ans = eval $try;
280 print "# For '$try'\n" if (!ok "$ans" , "ok" );
282 $try = "\$x = $class\->new(7); \$x = 0x20 ^ \$x;";
283 $try .= "'ok' if \$x == 0x27;"; $ans = eval $try;
284 print "# For '$try'\n" if (!ok "$ans" , "ok" );
286 ###############################################################################
287 # check badd(4,5) form
289 $try = "\$x = $class\->badd(4,5);";
290 $try .= "'ok' if \$x == 9;";
292 print "# For '$try'\n" if (!ok "$ans" , "ok" );
294 ###############################################################################
295 # check undefs: NOT DONE YET
297 ###############################################################################
300 $x = Math::BigInt->new(1); if ($x) { ok (1,1); } else { ok($x,'to be true') }
301 $x = Math::BigInt->new(0); if (!$x) { ok (1,1); } else { ok($x,'to be false') }
303 ###############################################################################
306 @args = Math::BigInt::objectify(2,4,5);
307 ok (scalar @args,3); # $class, 4, 5
308 ok ($args[0],$class);
312 @args = Math::BigInt::objectify(0,4,5);
313 ok (scalar @args,3); # $class, 4, 5
314 ok ($args[0],$class);
318 @args = Math::BigInt::objectify(2,4,5);
319 ok (scalar @args,3); # $class, 4, 5
320 ok ($args[0],$class);
324 @args = Math::BigInt::objectify(2,4,5,6,7);
325 ok (scalar @args,5); # $class, 4, 5, 6, 7
326 ok ($args[0],$class);
327 ok ($args[1],4); ok (ref($args[1]),$args[0]);
328 ok ($args[2],5); ok (ref($args[2]),$args[0]);
329 ok ($args[3],6); ok (ref($args[3]),'');
330 ok ($args[4],7); ok (ref($args[4]),'');
332 @args = Math::BigInt::objectify(2,$class,4,5,6,7);
333 ok (scalar @args,5); # $class, 4, 5, 6, 7
334 ok ($args[0],$class);
335 ok ($args[1],4); ok (ref($args[1]),$args[0]);
336 ok ($args[2],5); ok (ref($args[2]),$args[0]);
337 ok ($args[3],6); ok (ref($args[3]),'');
338 ok ($args[4],7); ok (ref($args[4]),'');
340 ###############################################################################
341 # test for floating-point input (other tests in bnorm() below)
343 $z = 1050000000000000; # may be int on systems with 64bit?
344 $x = $class->new($z); ok ($x->bsstr(),'105e+13'); # not 1.05e+15
345 $z = 1e+129; # definitely a float (may fail on UTS)
346 # don't compare to $z, since some Perl versions stringify $z into something
347 # like '1.e+129' or something equally ugly
348 $x = $class->new($z); ok ($x->bsstr(),'1e+129');
350 ###############################################################################
351 # prime number tests, also test for **= and length()
352 # found on: http://www.utm.edu/research/primes/notes/by_year.html
355 $x = $class->new(2); $x **= 148; $x++; $x = $x / 17;
356 ok ($x,"20988936657440586486151264256610222593863921");
357 ok ($x->length(),length "20988936657440586486151264256610222593863921");
360 $x = $class->new(2); $x **= 127; $x--;
361 ok ($x,"170141183460469231731687303715884105727");
363 $x = $class->new('215960156869840440586892398248');
364 ($x,$y) = $x->length();
365 ok ($x,30); ok ($y,0);
367 $x = $class->new('1_000_000_000_000');
368 ($x,$y) = $x->length();
369 ok ($x,13); ok ($y,0);
371 # I am afraid the following is not yet possible due to slowness
372 # Also, testing for 2 meg output is a bit hard ;)
373 #$x = $class->new(2); $x **= 6972593; $x--;
375 # 593573509*2^332162+1 has exactly 1,000,000 digits
376 # takes about 24 mins on 300 Mhz, so cannot be done yet ;)
377 #$x = $class->new(2); $x **= 332162; $x *= "593573509"; $x++;
378 #ok ($x->length(),1_000_000);
380 ###############################################################################
381 # inheritance and overriding of _swap
383 $x = Math::Foo->new(5);
384 $x = $x - 8; # 8 - 5 instead of 5-8
386 ok (ref($x),'Math::Foo');
388 $x = Math::Foo->new(5);
389 $x = 8 - $x; # 5 - 8 instead of 8 - 5
391 ok (ref($x),'Math::Foo');
393 ###############################################################################
394 # Test whether +inf eq inf
395 # This tried to test whether BigInt inf equals Perl inf. Unfortunately, Perl
396 # hasn't (before 5.7.3 at least) a consistent way to say inf, and some things
397 # like 1e100000 crash on some platforms. So simple test for the string 'inf'
398 $x = $class->new('+inf'); ok ($x,'inf');
400 ###############################################################################
401 ###############################################################################
402 # the followin tests only make sense with Math::BigInt::Calc
404 exit if $CALC ne 'Math::BigInt::Calc'; # for Pari et al.
406 ###############################################################################
407 # check proper length of internal arrays
409 my $bl = Math::BigInt::Calc::_base_len();
410 my $BASE = '9' x $bl;
414 $x = $class->new($MAX); is_valid($x); # f.i. 9999
415 $x += 1; ok ($x,$BASE); is_valid($x); # 10000
416 $x -= 1; ok ($x,$MAX); is_valid($x); # 9999 again
418 ###############################################################################
421 $x = $class->new($BASE-1); ok ($x->numify(),$BASE-1);
422 $x = $class->new(-($BASE-1)); ok ($x->numify(),-($BASE-1));
423 $x = $class->new($BASE); ok ($x->numify(),$BASE);
424 $x = $class->new(-$BASE); ok ($x->numify(),-$BASE);
425 $x = $class->new( -($BASE*$BASE*1+$BASE*1+1) );
426 ok($x->numify(),-($BASE*$BASE*1+$BASE*1+1));
428 ###############################################################################
429 # test bug in _digits with length($c[-1]) where $c[-1] was "00001" instead of 1
431 $x = Math::BigInt->new(99998); $x++; $x++; $x++; $x++;
432 if ($x > 100000) { ok (1,1) } else { ok ("$x < 100000","$x > 100000"); }
434 $x = Math::BigInt->new(100003); $x++;
435 $y = Math::BigInt->new(1000000);
436 if ($x < 1000000) { ok (1,1) } else { ok ("$x > 1000000","$x < 1000000"); }
438 ###############################################################################
439 # bug in sub where number with at least 6 trailing zeros after any op failed
441 $x = Math::BigInt->new(123456); $z = Math::BigInt->new(10000); $z *= 10;
446 ###############################################################################
447 # bug in shortcut in mul()
449 # construct a number with a zero-hole of BASE_LEN
450 $x = '1' x $bl . '0' x $bl . '1' x $bl . '0' x $bl;
452 $x = Math::BigInt->new($x)->bmul($y);
453 # result is 123..$bl . $bl x (3*bl-1) . $bl...321 . '0' x $bl
455 for (my $i = 1; $i <= $bl; $i++)
457 $y .= $i; $d = $i.$d;
459 $y .= $bl x (3*$bl-1) . $d . '0' x $bl;
462 ###############################################################################
463 # bug with rest "-0" in div, causing further div()s to fail
465 $x = Math::BigInt->new('-322056000'); ($x,$y) = $x->bdiv('-12882240');
467 ok ($y,'0','not -0'); # not '-0'
470 ### all tests done ############################################################
474 ###############################################################################
475 # Perl 5.005 does not like ok ($x,undef)
481 ok (1,1) and return if !defined $x;
485 ###############################################################################
486 # sub to check validity of a BigInt internally, to ensure that no op leaves a
487 # number object in an invalid state (f.i. "-0")
495 $e = 'Not a reference to Math::BigInt' if !ref($x);
498 $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'"
499 if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/;
501 $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0;
502 $e = $CALC->_check($x->{value}) if $e eq '0';
504 # test done, see if error did crop up
505 ok (1,1), return if ($e eq '0');
507 ok (1,$e." after op '$f'");
575 -123456789:+987654321:-1
576 +123456789:-987654321:-1
577 +987654321:+123456789:1
578 -987654321:+123456789:1
610 0b1000000000000000000000000000000:1073741824
621 0x1_2_3_4_56_78:305419896
636 # only one underscore between two digits
654 # bug with two E's in number beeing valid
674 -123456789:-123456789
683 # floating point input
691 # non-integer numbers
726 # it must be exactly /^[+-]inf$/
733 +1:+48:+281474976710656
736 +12345:4:10:123450000
742 1234567890123:12:10:1234567890123000000000000
747 +281474976710656:+48:+1
758 1230000000000:10:10:123
759 09876123456789067890:12:10:9876123
760 1234561234567890123:13:10:123456
774 +123456789:-123456789
775 -123456789:+123456789
783 +123456789:+123456789
784 -123456789:+123456789
809 -123456789:+987654321:-1
810 +123456789:-987654321:1
811 -987654321:+123456789:-1
870 +9999999:+1:+10000000
871 +99999999:+1:+100000000
872 +999999999:+1:+1000000000
873 +9999999999:+1:+10000000000
874 +99999999999:+1:+100000000000
881 +10000000:-1:+9999999
882 +100000000:-1:+99999999
883 +1000000000:-1:+999999999
884 +10000000000:-1:+9999999999
885 +123456789:+987654321:+1111111110
886 -123456789:+987654321:+864197532
887 -123456789:-987654321:-1111111110
888 +123456789:-987654321:-864197532
913 +99999999:+1:+99999998
914 +999999999:+1:+999999998
915 +9999999999:+1:+9999999998
916 +99999999999:+1:+99999999998
923 +10000000:-1:+10000001
924 +100000000:-1:+100000001
925 +1000000000:-1:+1000000001
926 +10000000000:-1:+10000000001
927 +123456789:+987654321:-864197532
928 -123456789:+987654321:-1111111110
929 -123456789:-987654321:+864197532
930 +123456789:-987654321:+1111111110
948 +123456789123456789:+0:+0
949 +0:+123456789123456789:+0
959 +10101:+10101:+102030201
960 +1001001:+1001001:+1002003002001
961 +100010001:+100010001:+10002000300020001
962 +10000100001:+10000100001:+100002000030000200001
963 +11111111111:+9:+99999999999
964 +22222222222:+9:+199999999998
965 +33333333333:+9:+299999999997
966 +44444444444:+9:+399999999996
967 +55555555555:+9:+499999999995
968 +66666666666:+9:+599999999994
969 +77777777777:+9:+699999999993
970 +88888888888:+9:+799999999992
971 +99999999999:+9:+899999999991
973 +12345:+12345:+152399025
974 +99999:+11111:+1111088889
976 99999:100000:9999900000
977 999999:1000000:999999000000
978 9999999:10000000:99999990000000
979 99999999:100000000:9999999900000000
980 999999999:1000000000:999999999000000000
981 9999999999:10000000000:99999999990000000000
982 99999999999:100000000000:9999999999900000000000
983 999999999999:1000000000000:999999999999000000000000
984 9999999999999:10000000000000:99999999999990000000000000
985 99999999999999:100000000000000:9999999999999900000000000000
986 999999999999999:1000000000000000:999999999999999000000000000000
987 9999999999999999:10000000000000000:99999999999999990000000000000000
988 99999999999999999:100000000000000000:9999999999999999900000000000000000
989 999999999999999999:1000000000000000000:999999999999999999000000000000000000
990 9999999999999999999:10000000000000000000:99999999999999999990000000000000000000
998 # inf handling and general remainder
1004 # see table in documentation in MBI
1023 # exceptions to reminder rule
1032 # inf handling (see table in doc)
1067 +1000000000:+9:+111111111
1068 +2000000000:+9:+222222222
1069 +3000000000:+9:+333333333
1070 +4000000000:+9:+444444444
1071 +5000000000:+9:+555555555
1072 +6000000000:+9:+666666666
1073 +7000000000:+9:+777777777
1074 +8000000000:+9:+888888888
1075 +9000000000:+9:+1000000000
1076 +35500000:+113:+314159
1077 +71000000:+226:+314159
1078 +106500000:+339:+314159
1079 +1000000000:+3:+333333333
1084 +999999999999:+9:+111111111111
1085 +999999999999:+99:+10101010101
1086 +999999999999:+999:+1001001001
1087 +999999999999:+9999:+100010001
1088 +999999999999999:+99999:+10000100001
1089 +1111088889:+99999:+11111
1104 # bug in Calc with '99999' vs $BASE-1
1105 10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576
1107 # inf handling, see table in doc
1126 # exceptions to reminder rule
1162 +999999999999:+99:+0
1163 +999999999999:+999:+0
1164 +999999999999:+9999:+0
1165 +999999999999999:+99999:+0
1179 152403346:12345:4321
1212 +281474976710656:+0:+0
1213 +281474976710656:+1:+0
1214 +281474976710656:+281474976710656:+281474976710656
1227 +281474976710656:+0:+281474976710656
1228 +281474976710656:+1:+281474976710657
1229 +281474976710656:+281474976710656:+281474976710656
1241 +281474976710656:+0:+281474976710656
1242 +281474976710656:+1:+281474976710657
1243 +281474976710656:+281474976710656:+0
1255 +281474976710656:-281474976710657
1335 -inf:1234500012:-inf
1336 +inf:-12345000123:inf
1337 -inf:-12345000123:-inf
1338 # 1 ** -x => 1 / (1 ** x)
1358 10:20:100000000000000000000
1359 123456:2:15241383936
1366 10000000000000000:17
1368 215960156869840440586892398248:30
1377 4000000000000:2000000
1383 $round_mode('trunc')
1393 +10123456789:5:+10123000000
1394 -10123456789:5:-10123000000
1395 +10123456789:9:+10123456700
1396 -10123456789:9:-10123456700
1397 +101234500:6:+101234000
1398 -101234500:6:-101234000
1399 #+101234500:-4:+101234000
1400 #-101234500:-4:-101234000
1402 +20123456789:5:+20123000000
1403 -20123456789:5:-20123000000
1404 +20123456789:9:+20123456800
1405 -20123456789:9:-20123456800
1406 +201234500:6:+201234000
1407 -201234500:6:-201234000
1408 #+201234500:-4:+201234000
1409 #-201234500:-4:-201234000
1410 +12345000:4:12340000
1411 -12345000:4:-12340000
1413 +30123456789:5:+30123000000
1414 -30123456789:5:-30123000000
1415 +30123456789:9:+30123456800
1416 -30123456789:9:-30123456800
1417 +301234500:6:+301235000
1418 -301234500:6:-301234000
1419 #+301234500:-4:+301235000
1420 #-301234500:-4:-301234000
1421 +12345000:4:12350000
1422 -12345000:4:-12340000
1424 +40123456789:5:+40123000000
1425 -40123456789:5:-40123000000
1426 +40123456789:9:+40123456800
1427 -40123456789:9:-40123456800
1428 +401234500:6:+401234000
1429 +401234500:6:+401234000
1430 #-401234500:-4:-401235000
1431 #-401234500:-4:-401235000
1432 +12345000:4:12340000
1433 -12345000:4:-12350000
1435 +50123456789:5:+50123000000
1436 -50123456789:5:-50123000000
1437 +50123456789:9:+50123456800
1438 -50123456789:9:-50123456800
1439 +501234500:6:+501235000
1440 -501234500:6:-501235000
1441 #+501234500:-4:+501235000
1442 #-501234500:-4:-501235000
1443 +12345000:4:12350000
1444 -12345000:4:-12350000
1446 +60123456789:5:+60123000000
1447 -60123456789:5:-60123000000
1448 +60123456789:9:+60123456800
1449 -60123456789:9:-60123456800
1450 +601234500:6:+601234000
1451 -601234500:6:-601234000
1452 #+601234500:-4:+601234000
1453 #-601234500:-4:-601234000
1460 +12345000:4:12340000
1461 -12345000:4:-12340000
1479 # floor and ceil tests are pretty pointless in integer space...but play safe
1506 0x123456789123456789:0x123456789123456789
1516 0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101