diff options
Diffstat (limited to 'lib/Math/BigInt')
-rw-r--r-- | lib/Math/BigInt/Calc.pm | 303 | ||||
-rwxr-xr-x | lib/Math/BigInt/t/bigfltpm.t | 203 | ||||
-rw-r--r-- | lib/Math/BigInt/t/bigintc.t | 139 | ||||
-rwxr-xr-x | lib/Math/BigInt/t/bigintpm.t | 227 | ||||
-rw-r--r-- | lib/Math/BigInt/t/mbimbf.t | 2 |
5 files changed, 693 insertions, 181 deletions
diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm index 23ff06329d..c42fc4043d 100644 --- a/lib/Math/BigInt/Calc.pm +++ b/lib/Math/BigInt/Calc.pm @@ -2,7 +2,7 @@ package Math::BigInt::Calc; use 5.005; use strict; -use warnings; +# use warnings; # dont use warnings for older Perls require Exporter; @@ -17,8 +17,9 @@ use vars qw/ @ISA @EXPORT $VERSION/; _is_zero _is_one _is_even _is_odd _check _zero _one _copy _zeros + _rsft _lsft ); -$VERSION = '0.06'; +$VERSION = '0.09'; # Package to store unsigned big integers in decimal and do math with them @@ -39,10 +40,37 @@ $VERSION = '0.06'; # constants for easier life my $nan = 'NaN'; -my $BASE_LEN = 5; + +my $BASE_LEN = 7; my $BASE = int("1e".$BASE_LEN); # var for trying to change it to 1e7 -my $RBASE = 1e-5; # see USE_MUL -my $class = 'Math::BigInt::Calc'; +my $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL + +BEGIN + { + # Daniel Pfeiffer: determine largest group of digits that is precisely + # multipliable with itself plus carry + my ($e, $num) = 4; + do { + $num = ('9' x ++$e) + 0; + $num *= $num + 1; + } until ($num == $num - 1 or $num - 1 == $num - 2); + $BASE_LEN = $e-1; + $BASE = int("1e".$BASE_LEN); + $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL + } + +# for quering and setting, to debug/benchmark things +sub _base_len + { + my $b = shift; + if (defined $b) + { + $BASE_LEN = $b; + $BASE = int("1e".$BASE_LEN); + $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL + } + $BASE_LEN; + } ############################################################################## # create objects from various representations @@ -52,12 +80,12 @@ sub _new # (string) return ref to num_array # Convert a number from string format to internal base 100000 format. # Assumes normalized value as input. - shift @_ if $_[0] eq $class; - my $d = shift; + my $d = $_[1]; # print "_new $d $$d\n"; my $il = CORE::length($$d)-1; # these leaves '00000' instead of int 0 and will be corrected after any op - return [ reverse(unpack("a" . ($il%5+1) . ("a5" x ($il/5)), $$d)) ]; + return [ reverse(unpack("a" . ($il % $BASE_LEN+1) + . ("a$BASE_LEN" x ($il / $BASE_LEN)), $$d)) ]; } sub _zero @@ -74,9 +102,7 @@ sub _one sub _copy { - shift @_ if $_[0] eq $class; - my $x = shift; - return [ @$x ]; + return [ @{$_[1]} ]; } ############################################################################## @@ -87,8 +113,7 @@ sub _str # (ref to BINT) return num_str # Convert number from internal base 100000 format to string format. # internal format is always normalized (no leading zeros, "-0" => "+0") - shift @_ if $_[0] eq $class; - my $ar = shift; + my $ar = $_[1]; my $ret = ""; my $l = scalar @$ar; # number of parts return $nan if $l < 1; # should not happen @@ -96,10 +121,11 @@ sub _str # leading zero parts in internal representation) $l --; $ret .= $ar->[$l]; $l--; # Interestingly, the pre-padd method uses more time - # the old grep variant takes longer (14 to 10 sec) + # the old grep variant takes longer (14 to 10 sec) + my $z = '0' x ($BASE_LEN-1); while ($l >= 0) { - $ret .= substr('0000'.$ar->[$l],-5); # fastest way I could think of + $ret .= substr($z.$ar->[$l],-$BASE_LEN); # fastest way I could think of $l--; } return \$ret; @@ -108,8 +134,7 @@ sub _str sub _num { # Make a number (scalar int/float) from a BigInt object - shift @_ if $_[0] eq $class; - my $x = shift; + my $x = $_[1]; return $x->[0] if scalar @$x == 1; # below $BASE my $fac = 1; my $num = 0; @@ -126,13 +151,12 @@ sub _num sub _add { # (ref to int_num_array, ref to int_num_array) - # routine to add two base 1e5 numbers + # routine to add two base 1eX numbers # stolen from Knuth Vol 2 Algorithm A pg 231 # there are separate routines to add and sub as per Knuth pg 233 # This routine clobbers up array x, but not y. - shift @_ if $_[0] eq $class; - my ($x,$y) = @_; + my ($c,$x,$y) = @_; # for each in Y, add Y to X and carry. If after that, something is left in # X, foreach in X add carry to X and then return X, carry @@ -155,10 +179,9 @@ sub _add sub _sub { # (ref to int_num_array, ref to int_num_array) - # subtract base 1e5 numbers -- stolen from Knuth Vol 2 pg 232, $x > $y + # subtract base 1eX numbers -- stolen from Knuth Vol 2 pg 232, $x > $y # subtract Y from X (X is always greater/equal!) by modifying x in place - shift @_ if $_[0] eq $class; - my ($sx,$sy,$s) = @_; + my ($c,$sx,$sy,$s) = @_; my $car = 0; my $i; my $j = 0; if (!$s) @@ -198,41 +221,39 @@ sub _mul # (BINT, BINT) return nothing # multiply two numbers in internal representation # modifies first arg, second need not be different from first - shift @_ if $_[0] eq $class; - my ($xv,$yv) = @_; + my ($c,$xv,$yv) = @_; my @prod = (); my ($prod,$car,$cty,$xi,$yi); # since multiplying $x with $x fails, make copy in this case - $yv = [@$xv] if "$xv" eq "$yv"; - # looping through @$y if $xi == 0 is silly! optimize it! + $yv = [@$xv] if "$xv" eq "$yv"; # same references? for $xi (@$xv) { $car = 0; $cty = 0; + + # slow variant +# for $yi (@$yv) +# { +# $prod = $xi * $yi + ($prod[$cty] || 0) + $car; +# $prod[$cty++] = +# $prod - ($car = int($prod * RBASE)) * $BASE; # see USE_MUL +# } +# $prod[$cty] += $car if $car; # need really to check for 0? +# $xi = shift @prod; + + # faster variant + # looping through this if $xi == 0 is silly - so optimize it away! + $xi = (shift @prod || 0), next if $xi == 0; for $yi (@$yv) { $prod = $xi * $yi + ($prod[$cty] || 0) + $car; +## this is actually a tad slower +## $prod = $prod[$cty]; $prod += ($car + $xi * $yi); # no ||0 here $prod[$cty++] = - $prod - ($car = int($prod * 1e-5)) * $BASE; # see USE_MUL + $prod - ($car = int($prod * $RBASE)) * $BASE; # see USE_MUL } $prod[$cty] += $car if $car; # need really to check for 0? $xi = shift @prod; } -# for $xi (@$xv) -# { -# $car = 0; $cty = 0; -# # looping through this if $xi == 0 is silly! optimize it! -# if (($xi||0) != 0) -# { -# for $yi (@$yv) -# { -# $prod = $prod[$cty]; $prod += ($car + $xi * $yi); # no ||0 here -# $prod[$cty++] = -# $prod - ($car = int($prod * 1e-5)) * $BASE; # see USE_MUL -# } -# } -# $prod[$cty] += $car if $car; # need really to check for 0? -# $xi = shift @prod; -# } push @$xv, @prod; __strip_zeros($xv); # normalize (handled last to save check for $y->is_zero() @@ -244,8 +265,7 @@ sub _div # ref to array, ref to array, modify first array and return remainder if # in list context # no longer handles sign - shift @_ if $_[0] eq $class; - my ($x,$yorg) = @_; + my ($c,$x,$yorg) = @_; my ($car,$bar,$prd,$dd,$xi,$yi,@q,$v2,$v1); my (@d,$tmp,$q,$u2,$u1,$u0); @@ -280,7 +300,7 @@ sub _div #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n" # if $v1 == 0; $q = (($u0 == $v1) ? 99999 : int(($u0*$BASE+$u1)/$v1)); - --$q while ($v2*$q > ($u0*1e5+$u1-$q*$v1)*$BASE+$u2); + --$q while ($v2*$q > ($u0*$BASE+$u1-$q*$v1)*$BASE+$u2); if ($q) { ($car, $bar) = (0,0); @@ -288,14 +308,14 @@ sub _div { $prd = $q * $y->[$yi] + $car; $prd -= ($car = int($prd * $RBASE)) * $BASE; # see USE_MUL - $x->[$xi] += 1e5 if ($bar = (($x->[$xi] -= $prd + $bar) < 0)); + $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0)); } if ($x->[-1] < $car + $bar) { $car = 0; --$q; for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi) { - $x->[$xi] -= 1e5 + $x->[$xi] -= $BASE if ($car = (($x->[$xi] += $y->[$yi] + $car) > $BASE)); } } @@ -330,6 +350,98 @@ sub _div } ############################################################################## +# shifts + +sub _rsft + { + my ($c,$x,$y,$n) = @_; + + if ($n != 10) + { + return; # we cant do this here, due to now _pow, so signal failure + } + else + { + # shortcut (faster) for shifting by 10) + # multiples of $BASE_LEN + my $dst = 0; # destination + my $src = _num($c,$y); # as normal int + my $rem = $src % $BASE_LEN; # reminder to shift + $src = int($src / $BASE_LEN); # source + if ($rem == 0) + { + splice (@$x,0,$src); # even faster, 38.4 => 39.3 + } + else + { + my $len = scalar @$x - $src; # elems to go + my $vd; my $z = '0'x $BASE_LEN; + $x->[scalar @$x] = 0; # avoid || 0 test inside loop + while ($dst < $len) + { + $vd = $z.$x->[$src]; + #print "$dst $src '$vd' "; + $vd = substr($vd,-$BASE_LEN,$BASE_LEN-$rem); + #print "'$vd' "; + $src++; + $vd = substr($z.$x->[$src],-$rem,$rem) . $vd; + #print "'$vd1' "; + #print "'$vd'\n"; + $vd = substr($vd,-$BASE_LEN,$BASE_LEN) if length($vd) > $BASE_LEN; + $x->[$dst] = int($vd); + $dst++; + } + splice (@$x,$dst) if $dst > 0; # kill left-over array elems + pop @$x if $x->[-1] == 0; # kill last element if 0 + } # else rem == 0 + } + $x; + } + +sub _lsft + { + my ($c,$x,$y,$n) = @_; + + if ($n != 10) + { + return; # we cant do this here, due to now _pow, so signal failure + } + else + { + # shortcut (faster) for shifting by 10) since we are in base 10eX + # multiples of $BASE_LEN: + my $src = scalar @$x; # source + my $len = _num($c,$y); # shift-len as normal int + my $rem = $len % $BASE_LEN; # reminder to shift + my $dst = $src + int($len/$BASE_LEN); # destination + my $vd; # further speedup + #print "src $src:",$x->[$src]||0," dst $dst:",$v->[$dst]||0," rem $rem\n"; + $x->[$src] = 0; # avoid first ||0 for speed + my $z = '0' x $BASE_LEN; + while ($src >= 0) + { + $vd = $x->[$src]; $vd = $z.$vd; + #print "s $src d $dst '$vd' "; + $vd = substr($vd,-$BASE_LEN+$rem,$BASE_LEN-$rem); + #print "'$vd' "; + $vd .= $src > 0 ? substr($z.$x->[$src-1],-$BASE_LEN,$rem) : '0' x $rem; + #print "'$vd' "; + $vd = substr($vd,-$BASE_LEN,$BASE_LEN) if length($vd) > $BASE_LEN; + #print "'$vd'\n"; + $x->[$dst] = int($vd); + $dst--; $src--; + } + # set lowest parts to 0 + while ($dst >= 0) { $x->[$dst--] = 0; } + # fix spurios last zero element + splice @$x,-1 if $x->[-1] == 0; + #print "elems: "; my $i = 0; + #foreach (reverse @$v) { print "$i $_ "; $i++; } print "\n"; + } + $x; + } + +############################################################################## # testing sub _acmp @@ -338,15 +450,16 @@ sub _acmp # ref to array, ref to array, return <0, 0, >0 # arrays must have at least one entry; this is not checked for - shift @_ if $_[0] eq $class; - my ($cx, $cy) = @_; + my ($c,$cx, $cy) = @_; #print "$cx $cy\n"; my ($i,$a,$x,$y,$k); # calculate length based on digits, not parts - $x = _len($cx); $y = _len($cy); + $x = _len('',$cx); $y = _len('',$cy); # print "length: ",($x-$y),"\n"; - return $x-$y if ($x - $y); # if different in length + my $lxy = $x - $y; # if different in length + return -1 if $lxy < 0; + return 1 if $lxy > 0; #print "full compare\n"; $i = 0; $a = 0; # first way takes 5.49 sec instead of 4.87, but has the early out advantage @@ -359,7 +472,9 @@ sub _acmp # print "$cx->[$j] $cy->[$j] $a",$cx->[$j]-$cy->[$j],"\n"; last if ($a = $cx->[$j] - $cy->[$j]); $j--; } - return $a; + return 1 if $a > 0; + return -1 if $a < 0; + return 0; # equal # while it early aborts, it is even slower than the manual variant #grep { return $a if ($a = $_ - $cy->[$i++]); } @$cx; # grep way, go trough all (bad for early ne) @@ -372,28 +487,25 @@ sub _len # computer number of digits in bigint, minus the sign # int() because add/sub sometimes leaves strings (like '00005') instead of # int ('5') in this place, causing length to fail - shift @_ if $_[0] eq $class; - my $cx = shift; + my $cx = $_[1]; - return (@$cx-1)*5+length(int($cx->[-1])); + return (@$cx-1)*$BASE_LEN+length(int($cx->[-1])); } sub _digit { # return the nth digit, negative values count backward # zero is rightmost, so _digit(123,0) will give 3 - shift @_ if $_[0] eq $class; - my $x = shift; - my $n = shift || 0; + my ($c,$x,$n) = @_; - my $len = _len($x); + my $len = _len('',$x); $n = $len+$n if $n < 0; # -1 last, -2 second-to-last $n = abs($n); # if negative was too big $len--; $n = $len if $n > $len; # n to big? - my $elem = int($n / 5); # which array element - my $digit = $n % 5; # which digit in this element + my $elem = int($n / $BASE_LEN); # which array element + my $digit = $n % $BASE_LEN; # which digit in this element $elem = '0000'.@$x[$elem]; # get element padded with 0's return substr($elem,-$digit-1,1); } @@ -403,20 +515,19 @@ sub _zeros # return amount of trailing zeros in decimal # check each array elem in _m for having 0 at end as long as elem == 0 # Upon finding a elem != 0, stop - shift @_ if $_[0] eq $class; - my $x = shift; + my $x = $_[1]; my $zeros = 0; my $elem; foreach my $e (@$x) { if ($e != 0) { - $elem = "$e"; # preserve x - $elem =~ s/.*?(0*$)/$1/; # strip anything not zero - $zeros *= 5; # elems * 5 - $zeros += CORE::length($elem); # count trailing zeros - last; # early out + $elem = "$e"; # preserve x + $elem =~ s/.*?(0*$)/$1/; # strip anything not zero + $zeros *= $BASE_LEN; # elems * 5 + $zeros += CORE::length($elem); # count trailing zeros + last; # early out } - $zeros ++; # real else branch: 50% slower! + $zeros ++; # real else branch: 50% slower! } return $zeros; } @@ -427,32 +538,28 @@ sub _zeros sub _is_zero { # return true if arg (BINT or num_str) is zero (array '+', '0') - shift @_ if $_[0] eq $class; - my ($x) = shift; + my $x = $_[1]; return (((scalar @$x == 1) && ($x->[0] == 0))) <=> 0; } sub _is_even { # return true if arg (BINT or num_str) is even - shift @_ if $_[0] eq $class; - my ($x) = shift; + my $x = $_[1]; return (!($x->[0] & 1)) <=> 0; } sub _is_odd { # return true if arg (BINT or num_str) is even - shift @_ if $_[0] eq $class; - my ($x) = shift; + my $x = $_[1]; return (($x->[0] & 1)) <=> 0; } sub _is_one { # return true if arg (BINT or num_str) is one (array '+', '1') - shift @_ if $_[0] eq $class; - my ($x) = shift; + my $x = $_[1]; return (scalar @$x == 1) && ($x->[0] == 1) <=> 0; } @@ -460,8 +567,6 @@ sub __strip_zeros { # internal normalization function that strips leading zeros from the array # args: ref to array - #trace(@_); - shift @_ if $_[0] eq $class; my $s = shift; my $cnt = scalar @$s; # get count of parts @@ -485,9 +590,8 @@ sub __strip_zeros sub _check { # no checks yet, pull it out from the test suite - shift @_ if $_[0] eq $class; + my $x = $_[1]; - my ($x) = shift; return "$x is not a reference" if !ref($x); # are all parts are valid? @@ -529,7 +633,7 @@ was rewritten to use library modules for core math routines. Any module which follows the same API as this can be used instead by using the following call: - use Math::BigInt Calc => BigNum; + use Math::BigInt lib => BigNum; =head1 EXPORT @@ -601,8 +705,32 @@ Input strings come in as unsigned but with prefix (i.e. as '123', '0xabc' or '0b1101'). Testing of input parameter validity is done by the caller, so you need not -worry about underflow (C<_sub()>, C<_dec()>) nor about division by zero or -similar cases. +worry about underflow (f.i. in C<_sub()>, C<_dec()>) nor about division by +zero or similar cases. + +The first parameter can be modified, that includes the possibility that you +return a reference to a completely different object instead. Although keeping +the reference the same is prefered. + +Return values are always references to objects or strings. Exceptions are +C<_lsft()> and C<_rsft()>, which return undef if they can not shift the +argument. This is used to delegate shifting of bases different than 10 back +to BigInt, which will use some generic code to calculate the result. + +=head1 WRAP YOUR OWN + +If you want to port your own favourite c-lib for big numbers to the +Math::BigInt interface, you can take any of the already existing modules as +a rough guideline. You should really wrap up the latest BigInt and BigFloat +testsuites with your module, and replace the following line: + + use Math::BigInt; + +by + + use Math::BigInt lib => 'yourlib'; + +This way you ensure that your library really works 100% within Math::BigInt. =head1 LICENSE @@ -617,6 +745,7 @@ Seperated from BigInt and shaped API with the help of John Peacock. =head1 SEE ALSO -L<Math::BigInt>, L<Math::BigFloat>. +L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigInt::BitVect> and +L<Math::BigInt::Pari>. =cut diff --git a/lib/Math/BigInt/t/bigfltpm.t b/lib/Math/BigInt/t/bigfltpm.t index e8a1cc2462..a30563d21e 100755 --- a/lib/Math/BigInt/t/bigfltpm.t +++ b/lib/Math/BigInt/t/bigfltpm.t @@ -8,11 +8,11 @@ BEGIN $| = 1; unshift @INC, '../lib'; # for running manually # chdir 't' if -d 't'; - plan tests => 945; + plan tests => 1158; } -use Math::BigFloat; use Math::BigInt; +use Math::BigFloat; my ($x,$y,$f,@args,$ans,$try,$ans1,$ans1_str,$setup); while (<DATA>) @@ -47,10 +47,21 @@ while (<DATA>) $try .= "\$x;"; } elsif ($f eq "binf") { $try .= "\$x->binf('$args[1]');"; + } elsif ($f eq "bnan") { + $try .= "\$x->bnan();"; + } elsif ($f eq "numify") { + $try .= "\$x->numify();"; + } elsif ($f eq "bone") { + $try .= "\$x->bone('$args[1]');"; + } elsif ($f eq "bstr") { + $try .= "\$x->accuracy($args[1]); \$x->precision($args[2]);"; + $try .= '$x->bstr();'; } elsif ($f eq "bsstr") { - $try .= "\$x->bsstr();"; + $try .= '$x->bsstr();'; + } elsif ($f eq "parts") { + $try .= '($a,$b) = $x->parts(); "$a $b";'; } elsif ($f eq "fneg") { - $try .= "-\$x;"; + $try .= '$x->bneg();'; } elsif ($f eq "bfloor") { $try .= "\$x->bfloor();"; } elsif ($f eq "bceil") { @@ -59,6 +70,10 @@ while (<DATA>) $try .= "\$x->is_zero()+0;"; } elsif ($f eq "is_one") { $try .= "\$x->is_one()+0;"; + } elsif ($f eq "is_positive") { + $try .= "\$x->is_positive()+0;"; + } elsif ($f eq "is_negative") { + $try .= "\$x->is_negative()+0;"; } elsif ($f eq "is_odd") { $try .= "\$x->is_odd()+0;"; } elsif ($f eq "is_even") { @@ -66,7 +81,11 @@ while (<DATA>) } elsif ($f eq "as_number") { $try .= "\$x->as_number();"; } elsif ($f eq "fabs") { - $try .= "abs \$x;"; + $try .= '$x->babs();'; + } elsif ($f eq "finc") { + $try .= '++$x;'; + } elsif ($f eq "fdec") { + $try .= '--$x;'; }elsif ($f eq "fround") { $try .= "$setup; \$x->fround($args[1]);"; } elsif ($f eq "ffround") { @@ -153,15 +172,48 @@ __END__ -123.456:-123 -200:-200 &binf -1:+:+inf +1:+:inf 2:-:-inf -3:abc:+inf -&bsstr -+inf:+inf +3:abc:inf +&numify +0:0e+1 ++1:1e+0 +1234:1234e+0 +NaN:NaN ++inf:inf -inf:-inf +&bnan abc:NaN +2:NaN +-2:NaN +0:NaN +&bone +2:+:1 +-2:-:-1 +-2:+:1 +2:-:-1 +0::1 +-2::1 +abc::1 +2:abc:1 +&bsstr ++inf:inf +-inf:-inf +abcbsstr:NaN +1234.567:1234567e-3 +&bstr ++inf:::inf +-inf:::-inf +abcbsstr:::NaN +1234.567:9::1234.56700 +1234.567::-6:1234.567000 +12345:5::12345 +0.001234:6::0.00123400 +0.001234::-8:0.00123400 +0:4::0 +0::-4:0.0000 &fnorm -+inf:+inf ++inf:inf -inf:-inf +infinity:NaN +-inf:NaN @@ -201,6 +253,14 @@ abc:NaN -123456E-2:-1234.56 1e1:10 2e-11:0.00000000002 +# excercise _split + .02e-1:0.002 + 000001:1 + -00001:-1 + -1:-1 + 000.01:0.01 + -000.0023:-0.0023 + 1.1e1:11 -3e111:-3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -4e-1111:-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 &fpow @@ -215,12 +275,14 @@ abc:NaN 128:-2:0.00006103515625 abc:123.456:NaN 123.456:abc:NaN -+inf:123.45:+inf ++inf:123.45:inf -inf:123.45:-inf -+inf:-123.45:+inf ++inf:-123.45:inf -inf:-123.45:-inf &fneg -abc:NaN +fnegNaN:NaN ++inf:-inf +-inf:inf +0:0 +1:-1 -1:1 @@ -229,7 +291,9 @@ abc:NaN +123.456789:-123.456789 -123456.789:123456.789 &fabs -abc:NaN +fabsNaN:NaN ++inf:inf +-inf:inf +0:0 +1:1 -1:1 @@ -239,6 +303,10 @@ abc:NaN -123456.789:123456.789 &fround $rnd_mode = "trunc" ++inf:5:inf +-inf:5:-inf +0:5:0 +NaNfround:5:NaN +10123456789:5:10123000000 -10123456789:5:-10123000000 +10123456789.123:5:10123000000 @@ -294,6 +362,10 @@ $rnd_mode = "even" -60123456789.0123:5:-60123000000 &ffround $rnd_mode = "trunc" ++inf:5:inf +-inf:5:-inf +0:5:0 +NaNffround:5:NaN +1.23:-1:1.2 +1.234:-1:1.2 +1.2345:-1:1.2 @@ -424,9 +496,9 @@ $rnd_mode = "even" 0.01234567:-9:0.01234567 0.01234567:-12:0.01234567 &fcmp -abc:abc: -abc:+0: -+0:abc: +fcmpNaN:fcmpNaN: +fcmpNaN:+0: ++0:fcmpNaN: +0:+0:0 -1:+0:-1 +0:-1:1 @@ -482,15 +554,43 @@ abc:+0: +inf:-54321.12345:1 +inf:+inf:0 -inf:-inf:0 ++inf:-inf:1 +-inf:+inf:-1 # return undef +inf:NaN: -NaN:+inf: +NaN:inf: -inf:NaN: NaN:-inf: +&fdec +fdecNaN:NaN ++inf:inf +-inf:-inf ++0:-1 ++1:0 +-1:-2 +1.23:0.23 +-1.23:-2.23 +&finc +fincNaN:NaN ++inf:inf +-inf:-inf ++0:1 ++1:2 +-1:0 +1.23:2.23 +-1.23:-0.23 &fadd 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 @@ -530,6 +630,14 @@ abc:+0:NaN abc:abc:NaN abc:+0:NaN +0:abc:NaN ++inf:-inf:inf +-inf:+inf:-inf ++inf:+inf:0 +-inf:-inf:0 +baddNaN:+inf:NaN +baddNaN:+inf:NaN ++inf:baddNaN:NaN +-inf:baddNaN:NaN +0:+0:0 +1:+0:1 +0:+1:-1 @@ -568,6 +676,22 @@ abc:+0:NaN abc:abc:NaN abc:+0:NaN +0:abc:NaN ++inf:NaNmul:NaN ++inf:NaNmul:NaN +NaNmul:+inf:NaN +NaNmul:-inf:NaN ++inf:+inf:inf ++inf:-inf:-inf ++inf:-inf:-inf ++inf:+inf:inf ++inf:123.34:inf ++inf:-123.34:-inf +-inf:123.34:-inf +-inf:-123.34:inf +123.34:+inf:inf +-123.34:+inf:-inf +123.34:-inf:-inf +-123.34:-inf:inf +0:+0:0 +0:+1:0 +1:+0:0 @@ -604,17 +728,23 @@ $div_scale = 40; $Math::BigFloat::rnd_mode = 'even' abc:abc:NaN abc:+1:abc:NaN +1:abc:NaN +-1:abc:NaN +0:abc:NaN +0:+0:NaN +0:+1:0 -+1:+0:NaN ++1:+0:inf ++3214:+0:inf +0:-1:0 --1:+0:NaN +-1:+0:-inf +-3214:+0:-inf +1:+1:1 -1:-1:1 +1:-1:-1 -1:+1:-1 +1:+2:0.5 +2:+1:2 +123:+inf:0 +123:-inf:0 +10:+5:2 +100:+4:25 +1000:+8:125 @@ -683,7 +813,7 @@ $div_scale = 40 -16:NaN -123.45:NaN nanfsqrt:NaN -+inf:+inf ++inf:inf -inf:NaN +1:1 +2:1.41421356237309504880168872420969807857 @@ -721,12 +851,39 @@ abc:0 -inf:0 123.456:0 -123.456:0 +&is_positive +0:1 +1:1 +-1:0 +-123:0 +NaN:0 +-inf:0 ++inf:1 +&is_negative +0:0 +1:0 +-1:1 +-123:1 +NaN:0 +-inf:1 ++inf:0 +&parts +0:0 1 +1:1 0 +123:123 0 +-123:-123 0 +-1200:-12 2 &is_zero NaNzero:0 ++inf:0 +-inf:0 0:1 -1:0 1:0 &is_one +NaNone:0 ++inf:0 +-inf:0 0:0 2:0 1:1 @@ -735,7 +892,7 @@ NaNzero:0 &bfloor 0:0 abc:NaN -+inf:+inf ++inf:inf -inf:-inf 1:1 -51:-51 @@ -744,7 +901,7 @@ abc:NaN &bceil 0:0 abc:NaN -+inf:+inf ++inf:inf -inf:-inf 1:1 -51:-51 diff --git a/lib/Math/BigInt/t/bigintc.t b/lib/Math/BigInt/t/bigintc.t index cb880bab68..9c82d65e0d 100644 --- a/lib/Math/BigInt/t/bigintc.t +++ b/lib/Math/BigInt/t/bigintc.t @@ -8,66 +8,121 @@ BEGIN $| = 1; # chdir 't' if -d 't'; unshift @INC, '../lib'; # for running manually - plan tests => 29; + plan tests => 52; } -# testing of Math::BigInt::Calc, primarily for interface/api and not for the +# testing of Math::BigInt::BitVect, primarily for interface/api and not for the # math functionality use Math::BigInt::Calc; -my $s123 = \'123'; my $s321 = \'321'; +my $C = 'Math::BigInt::Calc'; # pass classname to sub's + # _new and _str -my $x = _new($s123); my $u = _str($x); -ok ($$u,123); ok ($x->[0],123); ok (@$x,1); -my $y = _new($s321); +my $x = _new($C,\"123"); my $y = _new($C,\"321"); +ok (ref($x),'ARRAY'); ok (${_str($C,$x)},123); ok (${_str($C,$y)},321); # _add, _sub, _mul, _div -ok (${_str(_add($x,$y))},444); -ok (${_str(_sub($x,$y))},123); -ok (${_str(_mul($x,$y))},39483); -ok (${_str(_div($x,$y))},123); - -# division with reminder -my $z = _new(\"111"); - _mul($x,$y); -ok (${_str($x)},39483); -_add($x,$z); -ok (${_str($x)},39594); -my ($re,$rr) = _div($x,$y); +ok (${_str($C,_add($C,$x,$y))},444); +ok (${_str($C,_sub($C,$x,$y))},123); +ok (${_str($C,_mul($C,$x,$y))},39483); +ok (${_str($C,_div($C,$x,$y))},123); -ok (${_str($re)},123); ok (${_str($rr)},111); +ok (${_str($C,_mul($C,$x,$y))},39483); +ok (${_str($C,$x)},39483); +ok (${_str($C,$y)},321); +my $z = _new($C,\"2"); +ok (${_str($C,_add($C,$x,$z))},39485); +my ($re,$rr) = _div($C,$x,$y); -# _copy -$x = _new(\"12356"); -ok (${_str(_copy($x))},12356); - -# digit -$x = _new(\"123456789"); -ok (_digit($x,0),9); -ok (_digit($x,1),8); -ok (_digit($x,2),7); -ok (_digit($x,-1),1); -ok (_digit($x,-2),2); -ok (_digit($x,-3),3); +ok (${_str($C,$re)},123); ok (${_str($C,$rr)},2); # is_zero, _is_one, _one, _zero -$x = _new(\"12356"); -ok (_is_zero($x),0); -ok (_is_one($x),0); +ok (_is_zero($C,$x),0); +ok (_is_one($C,$x),0); -# _zeros -$x = _new(\"1256000000"); ok (_zeros($x),6); -$x = _new(\"152"); ok (_zeros($x),0); -$x = _new(\"123000"); ok (_zeros($x),3); +ok (_is_one($C,_one()),1); ok (_is_one($C,_zero()),0); +ok (_is_zero($C,_zero()),1); ok (_is_zero($C,_one()),0); + +# is_odd, is_even +ok (_is_odd($C,_one()),1); ok (_is_odd($C,_zero()),0); +ok (_is_even($C,_one()),0); ok (_is_even($C,_zero()),1); -ok (_is_one(_one()),1); ok (_is_one(_zero()),0); -ok (_is_zero(_zero()),1); ok (_is_zero(_one()),0); +# _digit +$x = _new($C,\"123456789"); +ok (_digit($C,$x,0),9); +ok (_digit($C,$x,1),8); +ok (_digit($C,$x,2),7); +ok (_digit($C,$x,-1),1); +ok (_digit($C,$x,-2),2); +ok (_digit($C,$x,-3),3); + +# _copy +$x = _new($C,\"12356"); +ok (${_str($C,_copy($C,$x))},12356); + +# _zeros +$x = _new($C,\"1256000000"); ok (_zeros($C,$x),6); +$x = _new($C,\"152"); ok (_zeros($C,$x),0); +$x = _new($C,\"123000"); ok (_zeros($C,$x),3); + +# _lsft, _rsft +$x = _new($C,\"10"); $y = _new($C,\"3"); +ok (${_str($C,_lsft($C,$x,$y,10))},10000); +$x = _new($C,\"20"); $y = _new($C,\"3"); +ok (${_str($C,_lsft($C,$x,$y,10))},20000); +$x = _new($C,\"128"); $y = _new($C,\"4"); +if (!defined _lsft($C,$x,$y,2)) + { + ok (1,1) + } +else + { + ok ('_lsft','undef'); + } +$x = _new($C,\"1000"); $y = _new($C,\"3"); +ok (${_str($C,_rsft($C,$x,$y,10))},1); +$x = _new($C,\"20000"); $y = _new($C,\"3"); +ok (${_str($C,_rsft($C,$x,$y,10))},20); +$x = _new($C,\"256"); $y = _new($C,\"4"); +if (!defined _rsft($C,$x,$y,2)) + { + ok (1,1) + } +else + { + ok ('_rsft','undef'); + } -ok (_check($x),0); -ok (_check(123),'123 is not a reference'); +# _acmp +$x = _new($C,\"123456789"); +$y = _new($C,\"987654321"); +ok (_acmp($C,$x,$y),-1); +ok (_acmp($C,$y,$x),1); +ok (_acmp($C,$x,$x),0); +ok (_acmp($C,$y,$y),0); + +# _div +$x = _new($C,\"3333"); $y = _new($C,\"1111"); +ok (${_str($C, scalar _div($C,$x,$y))},3); +$x = _new($C,\"33333"); $y = _new($C,\"1111"); ($x,$y) = _div($C,$x,$y); +ok (${_str($C,$x)},30); ok (${_str($C,$y)},3); +$x = _new($C,\"123"); $y = _new($C,\"1111"); +($x,$y) = _div($C,$x,$y); ok (${_str($C,$x)},0); ok (${_str($C,$y)},123); + +# _num +$x = _new($C,\"12345"); $x = _num($C,$x); ok (ref($x)||'',''); ok ($x,12345); + +# should not happen: +# $x = _new($C,\"-2"); $y = _new($C,\"4"); ok (_acmp($C,$x,$y),-1); + +# _check +$x = _new($C,\"123456789"); +ok (_check($C,$x),0); +ok (_check($C,123),'123 is not a reference'); # done 1; + diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t index f2663de26d..9e84e20ee6 100755 --- a/lib/Math/BigInt/t/bigintpm.t +++ b/lib/Math/BigInt/t/bigintpm.t @@ -8,9 +8,9 @@ BEGIN $| = 1; # chdir 't' if -d 't'; unshift @INC, '../lib'; # for running manually - plan tests => 1222; + plan tests => 1424; } -my $version = '1.36'; # for $VERSION tests, match current release (by hand!) +my $version = '1.40'; # for $VERSION tests, match current release (by hand!) ############################################################################## # for testing inheritance of _swap @@ -18,6 +18,7 @@ my $version = '1.36'; # for $VERSION tests, match current release (by hand!) package Math::Foo; use Math::BigInt; +#use Math::BigInt lib => 'BitVect'; # for testing use vars qw/@ISA/; @ISA = (qw/Math::BigInt/); @@ -46,9 +47,8 @@ package main; use Math::BigInt; #use Math::BigInt lib => 'BitVect'; # for testing -#use Math::BigInt lib => 'Small'; # for testing -my $CALC = Math::BigInt::_core_lib(); +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); @@ -81,10 +81,18 @@ while (<DATA>) $try .= '$x->is_odd()+0;'; } elsif ($f eq "is_even") { $try .= '$x->is_even()+0;'; + } elsif ($f eq "is_negative") { + $try .= '$x->is_negative()+0;'; + } elsif ($f eq "is_positive") { + $try .= '$x->is_positive()+0;'; } elsif ($f eq "is_inf") { $try .= "\$x->is_inf('$args[1]')+0;"; } 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") { @@ -92,9 +100,9 @@ while (<DATA>) } elsif ($f eq "bsstr") { $try .= '$x->bsstr();'; } elsif ($f eq "bneg") { - $try .= '-$x;'; + $try .= '$x->bneg();'; } elsif ($f eq "babs") { - $try .= 'abs $x;'; + $try .= '$x->babs();'; } elsif ($f eq "binc") { $try .= '++$x;'; } elsif ($f eq "bdec") { @@ -130,6 +138,8 @@ while (<DATA>) $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") @@ -199,7 +209,7 @@ while (<DATA>) } # endwhile data tests close DATA; -# XXX Tels 06/29/2001 following tests never fail or do not work :( +# 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');"; @@ -214,21 +224,27 @@ $ans1 = eval $try; ok ( $ans1, "1427247692705959881058285969449495136382746624"); # test wether Math::BigInt::Small via use works (w/ dff. spellings of calc) -#$try = "use Math::BigInt ($version,'CALC','Small');"; +#$try = "use Math::BigInt ($version,'lib','Small');"; #$try .= ' $x = 2**10; $x = "$x";'; #$ans1 = eval $try; #ok ( $ans1, "1024"); -#$try = "use Math::BigInt ($version,'cAlC','Math::BigInt::Small');"; +#$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,'CALC');"; +#$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++) @@ -237,11 +253,16 @@ for (my $i = 1; $i < 10; $i++) } ok "@a", "1 2 3 4 5 6 7 8 9"; -# test whether selfmultiplication works correctly (result is 2**64) +# 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) @@ -343,6 +364,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); @@ -350,8 +374,7 @@ $x += 1; ok ($x,100000); is_valid($x); $x -= 1; ok ($x,99999); is_valid($x); ############################################################################### -# check numify, these tests only make sense with Math::BigInt::Calc, since -# only this uses $BASE +# check numify my $BASE = int(1e5); # should access Math::BigInt::Calc::BASE $x = Math::BigInt->new($BASE-1); ok ($x->numify(),$BASE-1); @@ -380,6 +403,25 @@ 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'); @@ -477,6 +519,12 @@ ok ($x,-3); ok (ref($x),'Math::Foo'); ############################################################################### +# test whether +inf eq inf + +$y = 1e1000000; # create inf, since bareword inf does not work +$x = Math::BigInt->new('+inf'); ok ($x,$y); + +############################################################################### # all tests done ############################################################################### @@ -516,6 +564,20 @@ sub is_valid } __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 @@ -548,6 +610,24 @@ abc:0 +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 @@ -561,6 +641,8 @@ abc:0 0b011:3 0b101:5 0b1000000000000000000000000000000:1073741824 +0b_101:NaN +0b1_0_1:5 # hex input -0x0:0 0xabcdefgh:NaN @@ -569,8 +651,10 @@ abc:0 -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 @@ -621,10 +705,22 @@ E23:NaN -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 +1:+:inf 2:-:-inf -3:abc:+inf +3:abc:inf &is_inf +inf::1 -inf::1 @@ -677,6 +773,9 @@ abc:abc:NaN 100:1e+2 abc:NaN &bneg +bnegNaN:NaN ++inf:-inf +-inf:inf abd:NaN +0:+0 +1:-1 @@ -684,16 +783,18 @@ abd:NaN +123456789:-123456789 -123456789:+123456789 &babs -abc:NaN +babsNaN:NaN ++inf:inf +-inf:inf +0:+0 +1:+1 -1:+1 +123456789:+123456789 -123456789:+123456789 &bcmp -abc:abc: -abc:+0: -+0:abc: +bcmpNaN:bcmpNaN: +bcmpNaN:+0: ++0:bcmpNaN: +0:+0:0 -1:+0:-1 +0:-1:1 @@ -723,18 +824,24 @@ abc:+0: +inf:-5432112345:1 +inf:+inf:0 -inf:-inf:0 ++inf:-inf:1 +-inf:+inf:-1 # return undef +inf:NaN: -NaN:+inf: +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 @@ -742,6 +849,14 @@ abc:NaN 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 @@ -780,6 +895,10 @@ abc:+0:NaN 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 @@ -818,6 +937,14 @@ abc:+0:NaN 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 @@ -850,18 +977,23 @@ abc:+0:NaN +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 -# really? -#+5:0:+inf -#-5:0:-inf +1:abc:NaN +0:+0:NaN ++5:0:inf +-5:0:-inf ++1:+0:inf +0:+1:+0 -+1:+0:NaN +0:-1:+0 --1:+0:NaN +-1:+0:-inf +1:+1:+1 -1:-1:+1 +1:-1:-1 @@ -900,6 +1032,8 @@ abc:+1:abc:NaN 1:-3:-1 -5:3:-2 4:-3:-2 +123:+inf:0 +123:-inf:0 &bmod abc:abc:NaN abc:+1:abc:NaN @@ -948,6 +1082,7 @@ abc:+1:abc:NaN -2:-3:-2 4:-3:-2 1:-3:-2 +4095:4095:0 &bgcd abc:abc:NaN abc:+0:NaN @@ -983,6 +1118,12 @@ abc:0:NaN +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 @@ -992,6 +1133,11 @@ abc:0:NaN +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 @@ -1001,11 +1147,21 @@ abc:0:NaN +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 @@ -1075,9 +1231,9 @@ abc:12:NaN -2:-1:NaN 2:-2:NaN -2:-2:NaN -+inf:1234500012:+inf ++inf:1234500012:inf -inf:1234500012:-inf -+inf:-12345000123:+inf ++inf:-12345000123:inf -inf:-12345000123:-inf # 1 ** -x => 1 / (1 ** x) -1:0:1 @@ -1124,6 +1280,10 @@ abc:12: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 @@ -1201,11 +1361,16 @@ $round_mode('even') &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 @@ -1213,12 +1378,18 @@ NaNzero: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 diff --git a/lib/Math/BigInt/t/mbimbf.t b/lib/Math/BigInt/t/mbimbf.t index 3948102f0e..51cf41b212 100644 --- a/lib/Math/BigInt/t/mbimbf.t +++ b/lib/Math/BigInt/t/mbimbf.t @@ -157,7 +157,7 @@ $z = $y - $x; ok ($z,530.9); $z = $y * $x; ok ($z,80780); $z = $x ** 2; ok ($z,15241); $z = $x * $x; ok ($z,15241); -# not yet: $z = -$x; ok ($z,-123.46); ok ($x,123.456); +# not: $z = -$x; ok ($z,-123.46); ok ($x,123.456); $z = $x->copy(); $z->{_a} = 2; $z = $z / 2; ok ($z,62); $x = Math::BigFloat->new(123456); $x->{_a} = 4; $z = $x->copy; $z++; ok ($z,123500); |