From: Jarkko Hietaniemi Date: Sun, 4 Nov 2001 22:11:24 +0000 (+0000) Subject: The missing pieces from the Math::BigInt 1.45 puzzle. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=abcfbf5160a260774c4110b2927c8301d01b9ae0;p=p5sagit%2Fp5-mst-13.2.git The missing pieces from the Math::BigInt 1.45 puzzle. p4raw-id: //depot/perl@12848 --- diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index 0acd62a..bceefe0 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -391,7 +391,7 @@ sub bacmp my ($self,$x,$y) = objectify(2,@_); # handle +-inf and NaN's - if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]/) + if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/) { return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan)); return 0 if ($x->is_inf() && $y->is_inf()); @@ -764,7 +764,7 @@ sub bmod # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return reminder my ($self,$x,$y,$a,$p,$r) = objectify(2,@_); - return $x->bnan() if ($x->{sign} eq $nan || $y->is_nan() || $y->is_zero()); + return $x->bnan() if ($x->is_nan() || $y->is_nan() || $y->is_zero()); return $x->bzero() if $y->is_one(); # XXX tels: not done yet @@ -1157,8 +1157,8 @@ sub import } # any non :constant stuff is handled by our parent, Exporter # even if @_ is empty, to give it a chance - #$self->SUPER::import(@_); # does not work (would call MBI) - $self->export_to_level(1,$self,@_); # need this instead + $self->SUPER::import(@_); # for subclasses + $self->export_to_level(1,$self,@_); # need this, too } sub bnorm diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t index 6a8e68e..f4db9c3 100755 --- a/lib/Math/BigInt/t/bigintpm.t +++ b/lib/Math/BigInt/t/bigintpm.t @@ -1,1454 +1,21 @@ #!/usr/bin/perl -w -BEGIN { - $| = 1; - if ($ENV{PERL_CORE}) { - @INC = qw(../lib); - chdir 't' if -d 't'; - } else { - # for running manually with the CPAN distribution - unshift @INC, '../lib'; - } - print "# INC = @INC\n"; -} - -use strict; use Test; +use strict; -BEGIN - { - plan tests => 1457; - } - -my $version = '1.43'; # for $VERSION tests, match current release (by hand!) - -############################################################################## -# for testing inheritance of _swap - -package Math::Foo; - -use Math::BigInt; -#use Math::BigInt lib => 'BitVect'; # for testing -use vars qw/@ISA/; -@ISA = (qw/Math::BigInt/); - -use overload -# customized overload for sub, since original does not use swap there -'-' => sub { my @a = ref($_[0])->_swap(@_); - $a[0]->bsub($a[1])}; - -sub _swap +BEGIN { - # a fake _swap, which reverses the params - my $self = shift; # for override in subclass - if ($_[2]) - { - my $c = ref ($_[0] ) || 'Math::Foo'; - return ( $_[0]->copy(), $_[1] ); - } - else - { - return ( Math::Foo->new($_[1]), $_[0] ); - } + $| = 1; + unshift @INC, '../lib'; # for running manually + my $location = $0; $location =~ s/bigintpm.t//; + unshift @INC, $location; # to locate the testing files + # chdir 't' if -d 't'; + plan tests => 1608; } -############################################################################## -package main; - use Math::BigInt; -#use Math::BigInt lib => 'BitVect'; # for testing - -my $CALC = Math::BigInt::_core_lib(); ok ($CALC,'Math::BigInt::Calc'); - -my (@args,$f,$try,$x,$y,$z,$a,$exp,$ans,$ans1,@a,$m,$e,$round_mode); - -while () - { - chop; - next if /^#/; # skip comments - if (s/^&//) - { - $f = $_; - } - elsif (/^\$/) - { - $round_mode = $_; - $round_mode =~ s/^\$/Math::BigInt->/; - # print "$round_mode\n"; - } - else - { - @args = split(/:/,$_,99); - $ans = pop(@args); - $try = "\$x = Math::BigInt->new(\"$args[0]\");"; - if ($f eq "bnorm"){ - $try = "\$x = Math::BigInt::bnorm(\"$args[0]\");"; - } elsif ($f eq "is_zero") { - $try .= '$x->is_zero();'; - } elsif ($f eq "is_one") { - $try .= '$x->is_one();'; - } elsif ($f eq "is_odd") { - $try .= '$x->is_odd();'; - } elsif ($f eq "is_even") { - $try .= '$x->is_even();'; - } elsif ($f eq "is_negative") { - $try .= '$x->is_negative();'; - } elsif ($f eq "is_positive") { - $try .= '$x->is_positive();'; - } elsif ($f eq "as_hex") { - $try .= '$x->as_hex();'; - } elsif ($f eq "as_bin") { - $try .= '$x->as_bin();'; - } elsif ($f eq "is_inf") { - $try .= "\$x->is_inf('$args[1]');"; - } elsif ($f eq "binf") { - $try .= "\$x->binf('$args[1]');"; - } elsif ($f eq "bone") { - $try .= "\$x->bone('$args[1]');"; - } elsif ($f eq "bnan") { - $try .= "\$x->bnan();"; - } elsif ($f eq "bfloor") { - $try .= '$x->bfloor();'; - } elsif ($f eq "bceil") { - $try .= '$x->bceil();'; - } elsif ($f eq "bsstr") { - $try .= '$x->bsstr();'; - } elsif ($f eq "bneg") { - $try .= '$x->bneg();'; - } elsif ($f eq "babs") { - $try .= '$x->babs();'; - } elsif ($f eq "binc") { - $try .= '++$x;'; - } elsif ($f eq "bdec") { - $try .= '--$x;'; - }elsif ($f eq "bnot") { - $try .= '~$x;'; - }elsif ($f eq "bsqrt") { - $try .= '$x->bsqrt();'; - }elsif ($f eq "length") { - $try .= '$x->length();'; - }elsif ($f eq "exponent"){ - # ->bstr() to see if a BigInt is returned - $try .= '$x = $x->exponent()->bstr();'; - }elsif ($f eq "mantissa"){ - # ->bstr() to see if a BigInt is returned - $try .= '$x = $x->mantissa()->bstr();'; - }elsif ($f eq "parts"){ - $try .= '($m,$e) = $x->parts();'; - # ->bstr() to see if a BigInt is returned - $try .= '$m = $m->bstr(); $m = "NaN" if !defined $m;'; - $try .= '$e = $e->bstr(); $e = "NaN" if !defined $e;'; - $try .= '"$m,$e";'; - } else { - $try .= "\$y = new Math::BigInt ('$args[1]');"; - if ($f eq "bcmp"){ - $try .= '$x <=> $y;'; - }elsif ($f eq "bround") { - $try .= "$round_mode; \$x->bround(\$y);"; - }elsif ($f eq "bacmp"){ - $try .= '$x->bacmp($y);'; - }elsif ($f eq "badd"){ - $try .= '$x + $y;'; - }elsif ($f eq "bsub"){ - $try .= '$x - $y;'; - }elsif ($f eq "bmul"){ - $try .= '$x * $y;'; - }elsif ($f eq "bdiv"){ - $try .= '$x / $y;'; - }elsif ($f eq "bdiv-list"){ - $try .= 'join (",",$x->bdiv($y));'; - }elsif ($f eq "bmod"){ - $try .= '$x % $y;'; - }elsif ($f eq "bgcd") - { - if (defined $args[2]) - { - $try .= " \$z = new Math::BigInt \"$args[2]\"; "; - } - $try .= "Math::BigInt::bgcd(\$x, \$y"; - $try .= ", \$z" if (defined $args[2]); - $try .= " );"; - } - elsif ($f eq "blcm") - { - if (defined $args[2]) - { - $try .= " \$z = new Math::BigInt \"$args[2]\"; "; - } - $try .= "Math::BigInt::blcm(\$x, \$y"; - $try .= ", \$z" if (defined $args[2]); - $try .= " );"; - }elsif ($f eq "blsft"){ - if (defined $args[2]) - { - $try .= "\$x->blsft(\$y,$args[2]);"; - } - else - { - $try .= "\$x << \$y;"; - } - }elsif ($f eq "brsft"){ - if (defined $args[2]) - { - $try .= "\$x->brsft(\$y,$args[2]);"; - } - else - { - $try .= "\$x >> \$y;"; - } - }elsif ($f eq "band"){ - $try .= "\$x & \$y;"; - }elsif ($f eq "bior"){ - $try .= "\$x | \$y;"; - }elsif ($f eq "bxor"){ - $try .= "\$x ^ \$y;"; - }elsif ($f eq "bpow"){ - $try .= "\$x ** \$y;"; - }elsif ($f eq "digit"){ - $try = "\$x = Math::BigInt->new(\"$args[0]\"); \$x->digit($args[1]);"; - } else { warn "Unknown op '$f'"; } - } - # print "trying $try\n"; - $ans1 = eval $try; - $ans =~ s/^[+]([0-9])/$1/; # remove leading '+' - if ($ans eq "") - { - ok_undef ($ans1); - } - else - { - # print "try: $try ans: $ans1 $ans\n"; - print "# Tried: '$try'\n" if !ok ($ans1, $ans); - } - # check internal state of number objects - is_valid($ans1,$f) if ref $ans1; - } - } # endwhile data tests -close DATA; - -# XXX Tels 06/29/2001 following tests never fail or do not work :( !? - -# test whether use Math::BigInt qw/version/ works -$try = "use Math::BigInt ($version.'1');"; -$try .= ' $x = Math::BigInt->new(123); $x = "$x";'; -$ans1 = eval $try; -ok_undef ( $_ ); # should result in error! - -# test whether constant works or not, also test for qw($version) -$try = "use Math::BigInt ($version,'babs',':constant');"; -$try .= ' $x = 2**150; babs($x); $x = "$x";'; -$ans1 = eval $try; -ok ( $ans1, "1427247692705959881058285969449495136382746624"); - -# test wether Math::BigInt::Small via use works (w/ dff. spellings of calc) -#$try = "use Math::BigInt ($version,'lib','Small');"; -#$try .= ' $x = 2**10; $x = "$x";'; -#$ans1 = eval $try; -#ok ( $ans1, "1024"); -#$try = "use Math::BigInt ($version,'LiB','Math::BigInt::Small');"; -#$try .= ' $x = 2**10; $x = "$x";'; -#$ans1 = eval $try; -#ok ( $ans1, "1024"); -# test wether calc => undef (array element not existing) works -#$try = "use Math::BigInt ($version,'LIB');"; -#$try = "require Math::BigInt; Math::BigInt::import($version,'CALC');"; -#$try .= ' $x = Math::BigInt->new(2)**10; $x = "$x";'; -#$ans1 = eval $try; -#ok ( $ans1, 1024); - -# test whether fallback to calc works -$try = "use Math::BigInt ($version,'lib','foo, bar , ');"; -$try .= ' Math::BigInt::_core_lib();'; -$ans1 = eval $try; -ok ( $ans1, "Math::BigInt::Calc"); - -# test some more -@a = (); -for (my $i = 1; $i < 10; $i++) - { - push @a, $i; - } -ok "@a", "1 2 3 4 5 6 7 8 9"; - -# test whether self-multiplication works correctly (result is 2**64) -$try = '$x = new Math::BigInt "+4294967296";'; -$try .= '$a = $x->bmul($x);'; -$ans1 = eval $try; -print "# Tried: '$try'\n" if !ok ($ans1, Math::BigInt->new(2) ** 64); -# test self-pow -$try = '$x = Math::BigInt->new(10);'; -$try .= '$a = $x->bpow($x);'; -$ans1 = eval $try; -print "# Tried: '$try'\n" if !ok ($ans1, Math::BigInt->new(10) ** 10); - -# test whether op destroys args or not (should better not) - -$x = new Math::BigInt (3); -$y = new Math::BigInt (4); -$z = $x & $y; -ok ($x,3); -ok ($y,4); -ok ($z,0); -$z = $x | $y; -ok ($x,3); -ok ($y,4); -ok ($z,7); -$x = new Math::BigInt (1); -$y = new Math::BigInt (2); -$z = $x | $y; -ok ($x,1); -ok ($y,2); -ok ($z,3); - -$x = new Math::BigInt (5); -$y = new Math::BigInt (4); -$z = $x ^ $y; -ok ($x,5); -ok ($y,4); -ok ($z,1); - -$x = new Math::BigInt (-5); $y = -$x; -ok ($x, -5); - -$x = new Math::BigInt (-5); $y = abs($x); -ok ($x, -5); - -# check whether overloading cmp works -$try = "\$x = Math::BigInt->new(0);"; -$try .= "\$y = 10;"; -$try .= "'false' if \$x ne \$y;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "false" ); - -# we cant test for working cmpt with other objects here, we would need a dummy -# object with stringify overload for this. see Math::String tests - -############################################################################### -# check shortcuts -$try = "\$x = Math::BigInt->new(1); \$x += 9;"; -$try .= "'ok' if \$x == 10;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(1); \$x -= 9;"; -$try .= "'ok' if \$x == -8;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(1); \$x *= 9;"; -$try .= "'ok' if \$x == 9;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(10); \$x /= 2;"; -$try .= "'ok' if \$x == 5;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -############################################################################### -# check reversed order of arguments -$try = "\$x = Math::BigInt->new(10); \$x = 2 ** \$x;"; -$try .= "'ok' if \$x == 1024;"; $ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(10); \$x = 2 * \$x;"; -$try .= "'ok' if \$x == 20;"; $ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(10); \$x = 2 + \$x;"; -$try .= "'ok' if \$x == 12;"; $ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(10); \$x = 2 - \$x;"; -$try .= "'ok' if \$x == -8;"; $ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->new(10); \$x = 20 / \$x;"; -$try .= "'ok' if \$x == 2;"; $ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -############################################################################### -# check badd(4,5) form - -$try = "\$x = Math::BigInt::badd(4,5);"; -$try .= "'ok' if \$x == 9;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -$try = "\$x = Math::BigInt->badd(4,5);"; -$try .= "'ok' if \$x == 9;"; -$ans = eval $try; -print "# For '$try'\n" if (!ok "$ans" , "ok" ); - -############################################################################### -# the followin tests only make sense with Math::BigInt::Calc - -############################################################################### -# check proper length of internal arrays - -$x = Math::BigInt->new(99999); is_valid($x); -$x += 1; ok ($x,100000); is_valid($x); -$x -= 1; ok ($x,99999); is_valid($x); - -############################################################################### -# check numify -my $BASE = int(1e5); # should access Math::BigInt::Calc::BASE -$x = Math::BigInt->new($BASE-1); ok ($x->numify(),$BASE-1); -$x = Math::BigInt->new(-($BASE-1)); ok ($x->numify(),-($BASE-1)); -$x = Math::BigInt->new($BASE); ok ($x->numify(),$BASE); -$x = Math::BigInt->new(-$BASE); ok ($x->numify(),-$BASE); -$x = Math::BigInt->new( -($BASE*$BASE*1+$BASE*1+1) ); -ok($x->numify(),-($BASE*$BASE*1+$BASE*1+1)); - -############################################################################### -# test bug in _digits with length($c[-1]) where $c[-1] was "00001" instead of 1 - -$x = Math::BigInt->new(99998); $x++; $x++; $x++; $x++; -if ($x > 100000) { ok (1,1) } else { ok ("$x < 100000","$x > 100000"); } - -$x = Math::BigInt->new(100003); $x++; -$y = Math::BigInt->new(1000000); -if ($x < 1000000) { ok (1,1) } else { ok ("$x > 1000000","$x < 1000000"); } - -############################################################################### -# bug in sub where number with at least 6 trailing zeros after any op failed - -$x = Math::BigInt->new(123456); $z = Math::BigInt->new(10000); $z *= 10; -$x -= $z; -ok ($z, 100000); -ok ($x, 23456); - -############################################################################### -# bug in shortcut in mul() - -# construct a number with a zero-hole of BASE_LEN -my $bl = Math::BigInt::Calc::_base_len(); -$x = '1' x $bl . '0' x $bl . '1' x $bl . '0' x $bl; -$y = '1' x (2*$bl); -#print "$x * $y\n"; -$x = Math::BigInt->new($x)->bmul($y); -# result is 123..$bl . $bl x (3*bl-1) . $bl...321 . '0' x $bl -$y = ''; my $d = ''; -for (my $i = 1; $i <= $bl; $i++) - { - $y .= $i; $d = $i.$d; - } -#print "$y $d\n"; -$y .= $bl x (3*$bl-1) . $d . '0' x $bl; -ok ($x,$y); - -############################################################################### -# bug with rest "-0" in div, causing further div()s to fail - -$x = Math::BigInt->new('-322056000'); ($x,$y) = $x->bdiv('-12882240'); - -ok ($y,'0','not -0'); # not '-0' -is_valid($y); - -############################################################################### -# check undefs: NOT DONE YET - -############################################################################### -# bool - -$x = Math::BigInt->new(1); if ($x) { ok (1,1); } else { ok($x,'to be true') } -$x = Math::BigInt->new(0); if (!$x) { ok (1,1); } else { ok($x,'to be false') } - -############################################################################### -# objectify() - -@args = Math::BigInt::objectify(2,4,5); -ok (scalar @args,3); # 'Math::BigInt', 4, 5 -ok ($args[0],'Math::BigInt'); -ok ($args[1],4); -ok ($args[2],5); - -@args = Math::BigInt::objectify(0,4,5); -ok (scalar @args,3); # 'Math::BigInt', 4, 5 -ok ($args[0],'Math::BigInt'); -ok ($args[1],4); -ok ($args[2],5); - -@args = Math::BigInt::objectify(2,4,5); -ok (scalar @args,3); # 'Math::BigInt', 4, 5 -ok ($args[0],'Math::BigInt'); -ok ($args[1],4); -ok ($args[2],5); - -@args = Math::BigInt::objectify(2,4,5,6,7); -ok (scalar @args,5); # 'Math::BigInt', 4, 5, 6, 7 -ok ($args[0],'Math::BigInt'); -ok ($args[1],4); ok (ref($args[1]),$args[0]); -ok ($args[2],5); ok (ref($args[2]),$args[0]); -ok ($args[3],6); ok (ref($args[3]),''); -ok ($args[4],7); ok (ref($args[4]),''); - -@args = Math::BigInt::objectify(2,'Math::BigInt',4,5,6,7); -ok (scalar @args,5); # 'Math::BigInt', 4, 5, 6, 7 -ok ($args[0],'Math::BigInt'); -ok ($args[1],4); ok (ref($args[1]),$args[0]); -ok ($args[2],5); ok (ref($args[2]),$args[0]); -ok ($args[3],6); ok (ref($args[3]),''); -ok ($args[4],7); ok (ref($args[4]),''); - -############################################################################### -# test for floating-point input (other tests in bnorm() below) - -$z = 1050000000000000; # may be int on systems with 64bit? -$x = Math::BigInt->new($z); ok ($x->bsstr(),'105e+13'); # not 1.05e+15 -$z = 1e+129; # definitely a float (may fail on UTS) -# don't compare to $z, since some Perl versions stringify $z into something -# like '1.e+129' or something equally ugly -$x = Math::BigInt->new($z); ok ($x->bsstr(),'1e+129'); - -############################################################################### -# prime number tests, also test for **= and length() -# found on: http://www.utm.edu/research/primes/notes/by_year.html - -# ((2^148)-1)/17 -$x = Math::BigInt->new(2); $x **= 148; $x++; $x = $x / 17; -ok ($x,"20988936657440586486151264256610222593863921"); -ok ($x->length(),length "20988936657440586486151264256610222593863921"); - -# MM7 = 2^127-1 -$x = Math::BigInt->new(2); $x **= 127; $x--; -ok ($x,"170141183460469231731687303715884105727"); - -$x = Math::BigInt->new('215960156869840440586892398248'); -($x,$y) = $x->length(); -ok ($x,30); ok ($y,0); - -$x = Math::BigInt->new('1_000_000_000_000'); -($x,$y) = $x->length(); -ok ($x,13); ok ($y,0); - -# I am afraid the following is not yet possible due to slowness -# Also, testing for 2 meg output is a bit hard ;) -#$x = new Math::BigInt(2); $x **= 6972593; $x--; - -# 593573509*2^332162+1 has exactly 1,000,000 digits -# takes about 24 mins on 300 Mhz, so cannot be done yet ;) -#$x = Math::BigInt->new(2); $x **= 332162; $x *= "593573509"; $x++; -#ok ($x->length(),1_000_000); - -############################################################################### -# inheritance and overriding of _swap - -$x = Math::Foo->new(5); -$x = $x - 8; # 8 - 5 instead of 5-8 -ok ($x,3); -ok (ref($x),'Math::Foo'); - -$x = Math::Foo->new(5); -$x = 8 - $x; # 5 - 8 instead of 8 - 5 -ok ($x,-3); -ok (ref($x),'Math::Foo'); - -############################################################################### -# Test whether +inf eq inf -# This tried to test whether BigInt inf equals Perl inf. Unfortunately, Perl -# hasn't (before 5.7.3 at least) a consistent way to say inf, and some things -# like 1e100000 crash on some platforms. So simple test for the string 'inf' -$x = Math::BigInt->new('+inf'); ok ($x,'inf'); - -### all tests done ############################################################ - -############################################################################### -# Perl 5.005 does not like ok ($x,undef) - -sub ok_undef - { - my $x = shift; - - ok (1,1) and return if !defined $x; - ok ($x,'undef'); - } - -############################################################################### -# sub to check validity of a BigInt internally, to ensure that no op leaves a -# number object in an invalid state (f.i. "-0") - -sub is_valid - { - my ($x,$f) = @_; - - my $e = 0; # error? - # ok as reference? - $e = 'Not a reference to Math::BigInt' if !ref($x); - - # has ok sign? - $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'" - if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/; - - $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0; - $e = $CALC->_check($x->{value}) if $e eq '0'; - - # test done, see if error did crop up - ok (1,1), return if ($e eq '0'); - - ok (1,$e." op '$f'"); - } +use vars qw ($scale $class $try $x $y $f @args $ans $ans1 $ans1_str $setup); +$class = "Math::BigInt"; -__END__ -&is_negative -0:0 --1:1 -1:0 -+inf:0 --inf:1 -NaNneg:0 -&is_positive -0:1 --1:0 -1:1 -+inf:1 --inf:0 -NaNneg:0 -&is_odd -abc:0 -0:0 -1:1 -3:1 --1:1 --3:1 -10000001:1 -10000002:0 -2:0 -&is_even -abc:0 -0:1 -1:0 -3:0 --1:0 --3:0 -10000001:0 -10000002:1 -2:1 -&bacmp -+0:-0:0 -+0:+1:-1 --1:+1:0 -+1:-1:0 --1:+2:-1 -+2:-1:1 --123456789:+987654321:-1 -+123456789:-987654321:-1 -+987654321:+123456789:1 --987654321:+123456789:1 --123:+4567889:-1 -# NaNs -acmpNaN:123: -123:acmpNaN: -acmpNaN:acmpNaN: -# infinity -+inf:+inf:0 --inf:-inf:0 -+inf:-inf:0 --inf:+inf:0 -+inf:123:1 --inf:123:1 -+inf:-123:1 --inf:-123:1 -# return undef -+inf:NaN: -NaN:inf: --inf:NaN: -NaN:-inf: -&bnorm -123:123 -# binary input -0babc:NaN -0b123:NaN -0b0:0 --0b0:0 --0b1:-1 -0b0001:1 -0b001:1 -0b011:3 -0b101:5 -0b1000000000000000000000000000000:1073741824 -0b_101:NaN -0b1_0_1:5 -# hex input --0x0:0 -0xabcdefgh:NaN -0x1234:4660 -0xabcdef:11259375 --0xABCDEF:-11259375 --0x1234:-4660 -0x12345678:305419896 -0x1_2_3_4_56_78:305419896 -0x_123:NaN -# inf input -inf:inf -+inf:inf --inf:-inf -0inf:NaN -# normal input -:NaN -abc:NaN - 1 a:NaN -1bcd2:NaN -11111b:NaN -+1z:NaN --1z:NaN -0:0 -+0:0 -+00:0 -+000:0 -000000000000000000:0 --0:0 --0000:0 -+1:1 -+01:1 -+001:1 -+00000100000:100000 -123456789:123456789 --1:-1 --01:-1 --001:-1 --123456789:-123456789 --00000100000:-100000 -1_2_3:123 -_123:NaN -_123_:NaN -_123_:NaN -1__23:NaN -10000000000E-1_0:1 -1E2:100 -1E1:10 -1E0:1 -E1:NaN -E23:NaN -1.23E2:123 -1.23E1:NaN -1.23E-1:NaN -100E-1:10 -# floating point input -1.01E2:101 -1010E-1:101 --1010E0:-1010 --1010E1:-10100 --1010E-2:NaN --1.01E+1:NaN --1.01E-1:NaN -1234.00:1234 -&bnan -1:NaN -2:NaN -abc:NaN -&bone -2:+:+1 -2:-:-1 -boneNaN:-:-1 -boneNaN:+:+1 -2:abc:+1 -3::+1 -&binf -1:+:inf -2:-:-inf -3:abc:inf -&is_inf -+inf::1 --inf::1 -abc::0 -1::0 -NaN::0 --1::0 -+inf:-:0 -+inf:+:1 --inf:-:1 --inf:+:0 -# it must be exactly /^[+-]inf$/ -+infinity::0 --infinity::0 -&blsft -abc:abc:NaN -+2:+2:+8 -+1:+32:+4294967296 -+1:+48:+281474976710656 -+8:-2:NaN -# excercise base 10 -+12345:4:10:123450000 --1234:0:10:-1234 -+1234:0:10:+1234 -+2:2:10:200 -+12:2:10:1200 -+1234:-3:10:NaN -1234567890123:12:10:1234567890123000000000000 -&brsft -abc:abc:NaN -+8:+2:+2 -+4294967296:+32:+1 -+281474976710656:+48:+1 -+2:-2:NaN -# excercise base 10 --1234:0:10:-1234 -+1234:0:10:+1234 -+200:2:10:2 -+1234:3:10:1 -+1234:2:10:12 -+1234:-3:10:NaN -310000:4:10:31 -12300000:5:10:123 -1230000000000:10:10:123 -09876123456789067890:12:10:9876123 -1234561234567890123:13:10:123456 -&bsstr -1e+34:1e+34 -123.456E3:123456e+0 -100:1e+2 -abc:NaN -&bneg -bnegNaN:NaN -+inf:-inf --inf:inf -abd:NaN -+0:+0 -+1:-1 --1:+1 -+123456789:-123456789 --123456789:+123456789 -&babs -babsNaN:NaN -+inf:inf --inf:inf -+0:+0 -+1:+1 --1:+1 -+123456789:+123456789 --123456789:+123456789 -&bcmp -bcmpNaN:bcmpNaN: -bcmpNaN:+0: -+0:bcmpNaN: -+0:+0:0 --1:+0:-1 -+0:-1:1 -+1:+0:1 -+0:+1:-1 --1:+1:-1 -+1:-1:1 --1:-1:0 -+1:+1:0 -+123:+123:0 -+123:+12:1 -+12:+123:-1 --123:-123:0 --123:-12:-1 --12:-123:1 -+123:+124:-1 -+124:+123:1 --123:-124:1 --124:-123:-1 -+100:+5:1 --123456789:+987654321:-1 -+123456789:-987654321:1 --987654321:+123456789:-1 --inf:5432112345:-1 -+inf:5432112345:1 --inf:-5432112345:-1 -+inf:-5432112345:1 -+inf:+inf:0 --inf:-inf:0 -+inf:-inf:1 --inf:+inf:-1 -# return undef -+inf:NaN: -NaN:inf: --inf:NaN: -NaN:-inf: -&binc -abc:NaN -+inf:inf --inf:-inf -+0:+1 -+1:+2 --1:+0 -&bdec -abc:NaN -+inf:inf --inf:-inf -+0:-1 -+1:+0 --1:-2 -&badd -abc:abc:NaN -abc:+0:NaN -+0:abc:NaN -+inf:-inf:0 --inf:+inf:0 -+inf:+inf:inf --inf:-inf:-inf -baddNaN:+inf:NaN -baddNaN:+inf:NaN -+inf:baddNaN:NaN --inf:baddNaN:NaN -+0:+0:+0 -+1:+0:+1 -+0:+1:+1 -+1:+1:+2 --1:+0:-1 -+0:-1:-1 --1:-1:-2 --1:+1:+0 -+1:-1:+0 -+9:+1:+10 -+99:+1:+100 -+999:+1:+1000 -+9999:+1:+10000 -+99999:+1:+100000 -+999999:+1:+1000000 -+9999999:+1:+10000000 -+99999999:+1:+100000000 -+999999999:+1:+1000000000 -+9999999999:+1:+10000000000 -+99999999999:+1:+100000000000 -+10:-1:+9 -+100:-1:+99 -+1000:-1:+999 -+10000:-1:+9999 -+100000:-1:+99999 -+1000000:-1:+999999 -+10000000:-1:+9999999 -+100000000:-1:+99999999 -+1000000000:-1:+999999999 -+10000000000:-1:+9999999999 -+123456789:+987654321:+1111111110 --123456789:+987654321:+864197532 --123456789:-987654321:-1111111110 -+123456789:-987654321:-864197532 -&bsub -abc:abc:NaN -abc:+0:NaN -+0:abc:NaN -+inf:-inf:inf --inf:+inf:-inf -+inf:+inf:0 --inf:-inf:0 -+0:+0:+0 -+1:+0:+1 -+0:+1:-1 -+1:+1:+0 --1:+0:-1 -+0:-1:+1 --1:-1:+0 --1:+1:-2 -+1:-1:+2 -+9:+1:+8 -+99:+1:+98 -+999:+1:+998 -+9999:+1:+9998 -+99999:+1:+99998 -+999999:+1:+999998 -+9999999:+1:+9999998 -+99999999:+1:+99999998 -+999999999:+1:+999999998 -+9999999999:+1:+9999999998 -+99999999999:+1:+99999999998 -+10:-1:+11 -+100:-1:+101 -+1000:-1:+1001 -+10000:-1:+10001 -+100000:-1:+100001 -+1000000:-1:+1000001 -+10000000:-1:+10000001 -+100000000:-1:+100000001 -+1000000000:-1:+1000000001 -+10000000000:-1:+10000000001 -+123456789:+987654321:-864197532 --123456789:+987654321:-1111111110 --123456789:-987654321:+864197532 -+123456789:-987654321:+1111111110 -&bmul -abc:abc:NaN -abc:+0:NaN -+0:abc:NaN -NaNmul:+inf:NaN -NaNmul:-inf:NaN --inf:NaNmul:NaN -+inf:NaNmul:NaN -+inf:+inf:inf -+inf:-inf:-inf --inf:+inf:-inf --inf:-inf:inf -+0:+0:+0 -+0:+1:+0 -+1:+0:+0 -+0:-1:+0 --1:+0:+0 -+123456789123456789:+0:+0 -+0:+123456789123456789:+0 --1:-1:+1 --1:+1:-1 -+1:-1:-1 -+1:+1:+1 -+2:+3:+6 --2:+3:-6 -+2:-3:-6 --2:-3:+6 -+111:+111:+12321 -+10101:+10101:+102030201 -+1001001:+1001001:+1002003002001 -+100010001:+100010001:+10002000300020001 -+10000100001:+10000100001:+100002000030000200001 -+11111111111:+9:+99999999999 -+22222222222:+9:+199999999998 -+33333333333:+9:+299999999997 -+44444444444:+9:+399999999996 -+55555555555:+9:+499999999995 -+66666666666:+9:+599999999994 -+77777777777:+9:+699999999993 -+88888888888:+9:+799999999992 -+99999999999:+9:+899999999991 -+25:+25:+625 -+12345:+12345:+152399025 -+99999:+11111:+1111088889 -&bdiv-list -100:20:5,0 -4095:4095:1,0 --4095:-4095:1,0 -4095:-4095:-1,0 --4095:4095:-1,0 -&bdiv -abc:abc:NaN -abc:+1:abc:NaN -+1:abc:NaN -+0:+0:NaN -+5:0:inf --5:0:-inf -+1:+0:inf -+0:+1:+0 -+0:-1:+0 --1:+0:-inf -+1:+1:+1 --1:-1:+1 -+1:-1:-1 --1:+1:-1 -+1:+2:+0 -+2:+1:+2 -+1:+26:+0 -+1000000000:+9:+111111111 -+2000000000:+9:+222222222 -+3000000000:+9:+333333333 -+4000000000:+9:+444444444 -+5000000000:+9:+555555555 -+6000000000:+9:+666666666 -+7000000000:+9:+777777777 -+8000000000:+9:+888888888 -+9000000000:+9:+1000000000 -+35500000:+113:+314159 -+71000000:+226:+314159 -+106500000:+339:+314159 -+1000000000:+3:+333333333 -+10:+5:+2 -+100:+4:+25 -+1000:+8:+125 -+10000:+16:+625 -+999999999999:+9:+111111111111 -+999999999999:+99:+10101010101 -+999999999999:+999:+1001001001 -+999999999999:+9999:+100010001 -+999999999999999:+99999:+10000100001 -+1111088889:+99999:+11111 --5:-3:1 -4:3:1 -1:3:0 --2:-3:0 --2:3:-1 -1:-3:-1 --5:3:-2 -4:-3:-2 -123:+inf:0 -123:-inf:0 -10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576 -&bmod -abc:abc:NaN -abc:+1:abc:NaN -+1:abc:NaN -+0:+0:NaN -+0:+1:+0 -+1:+0:NaN -+0:-1:+0 --1:+0:NaN -+1:+1:+0 --1:-1:+0 -+1:-1:+0 --1:+1:+0 -+1:+2:+1 -+2:+1:+0 -+1000000000:+9:+1 -+2000000000:+9:+2 -+3000000000:+9:+3 -+4000000000:+9:+4 -+5000000000:+9:+5 -+6000000000:+9:+6 -+7000000000:+9:+7 -+8000000000:+9:+8 -+9000000000:+9:+0 -+35500000:+113:+33 -+71000000:+226:+66 -+106500000:+339:+99 -+1000000000:+3:+1 -+10:+5:+0 -+100:+4:+0 -+1000:+8:+0 -+10000:+16:+0 -+999999999999:+9:+0 -+999999999999:+99:+0 -+999999999999:+999:+0 -+999999999999:+9999:+0 -+999999999999999:+99999:+0 --9:+5:+1 -+9:-5:-1 --9:-5:-4 --5:3:1 --2:3:1 -4:3:1 -1:3:1 --5:-3:-2 --2:-3:-2 -4:-3:-2 -1:-3:-2 -4095:4095:0 -&bgcd -abc:abc:NaN -abc:+0:NaN -+0:abc:NaN -+0:+0:+0 -+0:+1:+1 -+1:+0:+1 -+1:+1:+1 -+2:+3:+1 -+3:+2:+1 --3:+2:+1 -+100:+625:+25 -+4096:+81:+1 -+1034:+804:+2 -+27:+90:+56:+1 -+27:+90:+54:+9 -&blcm -abc:abc:NaN -abc:+0:NaN -+0:abc:NaN -+0:+0:NaN -+1:+0:+0 -+0:+1:+0 -+27:+90:+270 -+1034:+804:+415668 -&band -abc:abc:NaN -abc:0:NaN -0:abc:NaN -1:2:0 -3:2:2 -+8:+2:+0 -+281474976710656:+0:+0 -+281474976710656:+1:+0 -+281474976710656:+281474976710656:+281474976710656 --2:-3:-4 --1:-1:-1 --6:-6:-6 --7:-4:-8 --7:4:0 --4:7:4 -&bior -abc:abc:NaN -abc:0:NaN -0:abc:NaN -1:2:3 -+8:+2:+10 -+281474976710656:+0:+281474976710656 -+281474976710656:+1:+281474976710657 -+281474976710656:+281474976710656:+281474976710656 --2:-3:-1 --1:-1:-1 --6:-6:-6 --7:4:-3 --4:7:-1 -&bxor -abc:abc:NaN -abc:0:NaN -0:abc:NaN -1:2:3 -+8:+2:+10 -+281474976710656:+0:+281474976710656 -+281474976710656:+1:+281474976710657 -+281474976710656:+281474976710656:+0 --2:-3:3 --1:-1:0 --6:-6:0 --7:4:-3 --4:7:-5 -4:-7:-3 --4:-7:5 -&bnot -abc:NaN -+0:-1 -+8:-9 -+281474976710656:-281474976710657 --1:0 --2:1 --12:11 -&digit -0:0:0 -12:0:2 -12:1:1 -123:0:3 -123:1:2 -123:2:1 -123:-1:1 -123:-2:2 -123:-3:3 -123456:0:6 -123456:1:5 -123456:2:4 -123456:3:3 -123456:4:2 -123456:5:1 -123456:-1:1 -123456:-2:2 -123456:-3:3 -100000:-3:0 -100000:0:0 -100000:1:0 -&mantissa -abc:NaN -1e4:1 -2e0:2 -123:123 --1:-1 --2:-2 -+inf:inf --inf:-inf -&exponent -abc:NaN -1e4:4 -2e0:0 -123:0 --1:0 --2:0 -0:1 -+inf:inf --inf:inf -&parts -abc:NaN,NaN -1e4:1,4 -2e0:2,0 -123:123,0 --1:-1,0 --2:-2,0 -0:0,1 -+inf:inf,inf --inf:-inf,inf -&bpow -abc:12:NaN -12:abc:NaN -0:0:1 -0:1:0 -0:2:0 -0:-1:NaN -0:-2:NaN -1:0:1 -1:1:1 -1:2:1 -1:3:1 -1:-1:1 -1:-2:1 -1:-3:1 -2:0:1 -2:1:2 -2:2:4 -2:3:8 -3:3:27 -2:-1:NaN --2:-1:NaN -2:-2:NaN --2:-2:NaN -+inf:1234500012:inf --inf:1234500012:-inf -+inf:-12345000123:inf --inf:-12345000123:-inf -# 1 ** -x => 1 / (1 ** x) --1:0:1 --2:0:1 --1:1:-1 --1:2:1 --1:3:-1 --1:4:1 --1:5:-1 --1:-1:-1 --1:-2:1 --1:-3:-1 --1:-4:1 -10:2:100 -10:3:1000 -10:4:10000 -10:5:100000 -10:6:1000000 -10:7:10000000 -10:8:100000000 -10:9:1000000000 -10:20:100000000000000000000 -123456:2:15241383936 -&length -100:3 -10:2 -1:1 -0:1 -12345:5 -10000000000000000:17 --123:3 -215960156869840440586892398248:30 -&bsqrt -144:12 -16:4 -4:2 -2:1 -12:3 -256:16 -100000000:10000 -4000000000000:2000000 -1:1 -0:0 --2:NaN -Nan:NaN -&bround -$round_mode('trunc') -0:12:0 -NaNbround:12:NaN -+inf:12:inf --inf:12:-inf -1234:0:1234 -1234:2:1200 -123456:4:123400 -123456:5:123450 -123456:6:123456 -+10123456789:5:+10123000000 --10123456789:5:-10123000000 -+10123456789:9:+10123456700 --10123456789:9:-10123456700 -+101234500:6:+101234000 --101234500:6:-101234000 -#+101234500:-4:+101234000 -#-101234500:-4:-101234000 -$round_mode('zero') -+20123456789:5:+20123000000 --20123456789:5:-20123000000 -+20123456789:9:+20123456800 --20123456789:9:-20123456800 -+201234500:6:+201234000 --201234500:6:-201234000 -#+201234500:-4:+201234000 -#-201234500:-4:-201234000 -+12345000:4:12340000 --12345000:4:-12340000 -$round_mode('+inf') -+30123456789:5:+30123000000 --30123456789:5:-30123000000 -+30123456789:9:+30123456800 --30123456789:9:-30123456800 -+301234500:6:+301235000 --301234500:6:-301234000 -#+301234500:-4:+301235000 -#-301234500:-4:-301234000 -+12345000:4:12350000 --12345000:4:-12340000 -$round_mode('-inf') -+40123456789:5:+40123000000 --40123456789:5:-40123000000 -+40123456789:9:+40123456800 --40123456789:9:-40123456800 -+401234500:6:+401234000 -+401234500:6:+401234000 -#-401234500:-4:-401235000 -#-401234500:-4:-401235000 -+12345000:4:12340000 --12345000:4:-12350000 -$round_mode('odd') -+50123456789:5:+50123000000 --50123456789:5:-50123000000 -+50123456789:9:+50123456800 --50123456789:9:-50123456800 -+501234500:6:+501235000 --501234500:6:-501235000 -#+501234500:-4:+501235000 -#-501234500:-4:-501235000 -+12345000:4:12350000 --12345000:4:-12350000 -$round_mode('even') -+60123456789:5:+60123000000 --60123456789:5:-60123000000 -+60123456789:9:+60123456800 --60123456789:9:-60123456800 -+601234500:6:+601234000 --601234500:6:-601234000 -#+601234500:-4:+601234000 -#-601234500:-4:-601234000 -#-601234500:-9:0 -#-501234500:-9:0 -#-601234500:-8:0 -#-501234500:-8:0 -+1234567:7:1234567 -+1234567:6:1234570 -+12345000:4:12340000 --12345000:4:-12340000 -&is_zero -0:1 -NaNzero:0 -+inf:0 --inf:0 -123:0 --1:0 -1:0 -&is_one -0:0 -NaNone:0 -+inf:0 --inf:0 -1:1 -2:0 --1:0 --2:0 -# floor and ceil tests are pretty pointless in integer space...but play safe -&bfloor -0:0 -NaNfloor:NaN -+inf:inf --inf:-inf --1:-1 --2:-2 -2:2 -3:3 -abc:NaN -&bceil -NaNceil:NaN -+inf:inf --inf:-inf -0:0 --1:-1 --2:-2 -2:2 -3:3 -abc:NaN -&as_hex -128:0x80 --128:-0x80 -0:0x0 --0:0x0 -1:0x1 -0x123456789123456789:0x123456789123456789 -+inf:inf --inf:-inf -NaNas_hex:NaN -&as_bin -128:0b10000000 --128:-0b10000000 -0:0b0 --0:0b0 -1:0b1 -0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101 -+inf:inf --inf:-inf -NaNas_bin:NaN +require 'bigintpm.inc'; # all tests here for sharing