summaryrefslogtreecommitdiff
path: root/lib/Math/BigInt
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>2004-02-19 21:17:10 +0000
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2004-02-19 21:17:10 +0000
commit9b924220109ab5ca4ffe2f23c240236dc5a723c2 (patch)
tree69c11d167bab8903a99a104bdf2a59ab8f7343b6 /lib/Math/BigInt
parentb6a15bc5202dd52395ce566b43e1490d38dc2141 (diff)
downloadperl-9b924220109ab5ca4ffe2f23c240236dc5a723c2.tar.gz
Upgrade to prereleases of Math::BigInt 1.70 and
Math::BigRat 0.12, by Tels. p4raw-id: //depot/perl@22344
Diffstat (limited to 'lib/Math/BigInt')
-rw-r--r--lib/Math/BigInt/Calc.pm175
-rw-r--r--lib/Math/BigInt/CalcEmu.pm358
-rw-r--r--lib/Math/BigInt/t/bare_mbf.t2
-rw-r--r--lib/Math/BigInt/t/bare_mbi.t2
-rw-r--r--lib/Math/BigInt/t/bare_mif.t2
-rw-r--r--lib/Math/BigInt/t/bigfltpm.inc33
-rwxr-xr-xlib/Math/BigInt/t/bigfltpm.t4
-rw-r--r--lib/Math/BigInt/t/bigintc.t358
-rw-r--r--lib/Math/BigInt/t/bigintpm.inc36
-rwxr-xr-xlib/Math/BigInt/t/bigintpm.t2
-rw-r--r--lib/Math/BigInt/t/bigints.t67
-rw-r--r--lib/Math/BigInt/t/biglog.t11
-rw-r--r--lib/Math/BigInt/t/calling.t19
-rw-r--r--lib/Math/BigInt/t/config.t2
-rw-r--r--lib/Math/BigInt/t/mbimbf.inc24
-rw-r--r--lib/Math/BigInt/t/mbimbf.t7
-rw-r--r--lib/Math/BigInt/t/req_mbfw.t5
-rwxr-xr-xlib/Math/BigInt/t/sub_mbf.t2
-rwxr-xr-xlib/Math/BigInt/t/sub_mbi.t2
-rw-r--r--lib/Math/BigInt/t/sub_mif.t2
-rw-r--r--lib/Math/BigInt/t/upgrade.inc12
-rw-r--r--lib/Math/BigInt/t/upgrade.t2
-rw-r--r--lib/Math/BigInt/t/use_mbfw.t8
-rw-r--r--lib/Math/BigInt/t/with_sub.t5
24 files changed, 464 insertions, 676 deletions
diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm
index 1dd7619be2..f2f0c87466 100644
--- a/lib/Math/BigInt/Calc.pm
+++ b/lib/Math/BigInt/Calc.pm
@@ -6,7 +6,7 @@ use strict;
use vars qw/$VERSION/;
-$VERSION = '0.38';
+$VERSION = '0.40';
# Package to store unsigned big integers in decimal and do math with them
@@ -31,6 +31,9 @@ $VERSION = '0.38';
##############################################################################
# global constants, flags and accessory
+
+# announce that we are compatible with MBI v1.70 and up
+sub api_version () { 1; }
# constants for easier life
my $nan = 'NaN';
@@ -70,9 +73,6 @@ sub _base_len
$RBASE = abs('1e-'.$BASE_LEN_SMALL); # see USE_MUL
$MAX_VAL = $MBASE-1;
- #print "BASE_LEN: $BASE_LEN MAX_VAL: $MAX_VAL BASE: $BASE RBASE: $RBASE ";
- #print "BASE_LEN_SMALL: $BASE_LEN_SMALL MBASE: $MBASE\n";
-
undef &_mul;
undef &_div;
@@ -82,14 +82,12 @@ sub _base_len
# & here.
if ($caught == 2) # 2
{
- # print "# use mul\n";
# must USE_MUL since we cannot use DIV
*{_mul} = \&_mul_use_mul;
*{_div} = \&_div_use_mul;
}
else # 0 or 1
{
- # print "# use div\n";
# can USE_DIV instead
*{_mul} = \&_mul_use_div;
*{_div} = \&_div_use_div;
@@ -190,22 +188,21 @@ sub _new
# (ref to string) return ref to num_array
# Convert a number from string format (without sign) to internal base
# 1ex format. Assumes normalized value as input.
- my $d = $_[1];
- my $il = length($$d)-1;
+ my $il = length($_[1])-1;
# < BASE_LEN due len-1 above
- return [ int($$d) ] if $il < $BASE_LEN; # shortcut for short numbers
+ return [ int($_[1]) ] if $il < $BASE_LEN; # shortcut for short numbers
# this leaves '00000' instead of int 0 and will be corrected after any op
[ reverse(unpack("a" . ($il % $BASE_LEN+1)
- . ("a$BASE_LEN" x ($il / $BASE_LEN)), $$d)) ];
+ . ("a$BASE_LEN" x ($il / $BASE_LEN)), $_[1])) ];
}
BEGIN
{
- $AND_MASK = __PACKAGE__->_new( \( 2 ** $AND_BITS ));
- $XOR_MASK = __PACKAGE__->_new( \( 2 ** $XOR_BITS ));
- $OR_MASK = __PACKAGE__->_new( \( 2 ** $OR_BITS ));
+ $AND_MASK = __PACKAGE__->_new( ( 2 ** $AND_BITS ));
+ $XOR_MASK = __PACKAGE__->_new( ( 2 ** $XOR_BITS ));
+ $OR_MASK = __PACKAGE__->_new( ( 2 ** $OR_BITS ));
}
sub _zero
@@ -226,6 +223,12 @@ sub _two
[ 2 ];
}
+sub _ten
+ {
+ # create a 10 (used internally for shifting)
+ [ 10 ];
+ }
+
sub _copy
{
# make a true copy
@@ -260,14 +263,15 @@ sub _str
$ret .= substr($z.$ar->[$l],-$BASE_LEN); # fastest way I could think of
$l--;
}
- \$ret;
+ $ret;
}
sub _num
{
- # Make a number (scalar int/float) from a BigInt object
+ # Make a number (scalar int/float) from a BigInt object
my $x = $_[1];
- return $x->[0] if scalar @$x == 1; # below $BASE
+
+ return 0+$x->[0] if scalar @$x == 1; # below $BASE
my $fac = 1;
my $num = 0;
foreach (@$x)
@@ -354,7 +358,6 @@ sub _sub
my $car = 0; my $i; my $j = 0;
if (!$s)
{
- #print "case 2\n";
for $i (@$sx)
{
last unless defined $sy->[$j] || $car;
@@ -363,7 +366,6 @@ sub _sub
# might leave leading zeros, so fix that
return __strip_zeros($sx);
}
- #print "case 1 (swap)\n";
for $i (@$sx)
{
# we can't do an early out if $x is < than $y, since we
@@ -976,6 +978,9 @@ sub _zeros
# check each array elem in _m for having 0 at end as long as elem == 0
# Upon finding a elem != 0, stop
my $x = $_[1];
+
+ return 0 if scalar @$x == 1 && $x->[0] == 0;
+
my $zeros = 0; my $elem;
foreach my $e (@$x)
{
@@ -997,33 +1002,38 @@ sub _zeros
sub _is_zero
{
- # return true if arg (BINT or num_str) is zero (array '+', '0')
- my $x = $_[1];
-
- (((scalar @$x == 1) && ($x->[0] == 0))) <=> 0;
+ # return true if arg is zero
+ (((scalar @{$_[1]} == 1) && ($_[1]->[0] == 0))) <=> 0;
}
sub _is_even
{
- # return true if arg (BINT or num_str) is even
- my $x = $_[1];
- (!($x->[0] & 1)) <=> 0;
+ # return true if arg is even
+ (!($_[1]->[0] & 1)) <=> 0;
}
sub _is_odd
{
- # return true if arg (BINT or num_str) is even
- my $x = $_[1];
-
- (($x->[0] & 1)) <=> 0;
+ # return true if arg is even
+ (($_[1]->[0] & 1)) <=> 0;
}
sub _is_one
{
- # return true if arg (BINT or num_str) is one (array '+', '1')
- my $x = $_[1];
+ # return true if arg is one
+ (scalar @{$_[1]} == 1) && ($_[1]->[0] == 1) <=> 0;
+ }
+
+sub _is_two
+ {
+ # return true if arg is two
+ (scalar @{$_[1]} == 1) && ($_[1]->[0] == 2) <=> 0;
+ }
- (scalar @$x == 1) && ($x->[0] == 1) <=> 0;
+sub _is_ten
+ {
+ # return true if arg is ten
+ (scalar @{$_[1]} == 1) && ($_[1]->[0] == 10) <=> 0;
}
sub __strip_zeros
@@ -1086,8 +1096,6 @@ sub _check
###############################################################################
-###############################################################################
-# some optional routines to make BigInt faster
sub _mod
{
@@ -1160,7 +1168,7 @@ sub _rsft
if ($n != 10)
{
- $n = _new($c,\$n); return _div($c,$x, _pow($c,$n,$y));
+ $n = _new($c,$n); return _div($c,$x, _pow($c,$n,$y));
}
# shortcut (faster) for shifting by 10)
@@ -1208,7 +1216,7 @@ sub _lsft
if ($n != 10)
{
- $n = _new($c,\$n); return _mul($c,$x, _pow($c,$n,$y));
+ $n = _new($c,$n); return _mul($c,$x, _pow($c,$n,$y));
}
# shortcut (faster) for shifting by 10) since we are in base 10eX
@@ -1260,7 +1268,7 @@ sub _pow
my $pow2 = _one();
- my $y_bin = ${_as_bin($c,$cy)}; $y_bin =~ s/^0b//;
+ my $y_bin = _as_bin($c,$cy); $y_bin =~ s/^0b//;
my $len = length($y_bin);
while (--$len > 0)
{
@@ -1354,6 +1362,8 @@ sub _fac
$cx; # return result
}
+#############################################################################
+
sub _log_int
{
# calculate integer log of $x to base $base
@@ -1422,7 +1432,7 @@ sub _log_int
my $a;
my $base_mul = _mul($c, _copy($c,$base), $base);
- while (($a = _acmp($x,$trial,$x_org)) < 0)
+ while (($a = _acmp($c,$trial,$x_org)) < 0)
{
_mul($c,$trial,$base_mul); _add($c, $x, [2]);
}
@@ -1433,7 +1443,7 @@ sub _log_int
# overstepped the result
_dec($c, $x);
_div($c,$trial,$base);
- $a = _acmp($x,$trial,$x_org);
+ $a = _acmp($c,$trial,$x_org);
if ($a > 0)
{
_dec($c, $x);
@@ -1507,7 +1517,7 @@ sub _sqrt
# an even better guess. Not implemented yet. Does it improve performance?
$x->[$l--] = 0 while ($l >= 0); # all other digits of guess are zero
- print "start x= ",${_str($c,$x)},"\n" if DEBUG;
+ print "start x= ",_str($c,$x),"\n" if DEBUG;
my $two = _two();
my $last = _zero();
my $lastlast = _zero();
@@ -1519,7 +1529,7 @@ sub _sqrt
$last = _copy($c,$x);
_add($c,$x, _div($c,_copy($c,$y),$x));
_div($c,$x, $two );
- print " x= ",${_str($c,$x)},"\n" if DEBUG;
+ print " x= ",_str($c,$x),"\n" if DEBUG;
}
print "\nsteps in sqrt: $steps, " if DEBUG;
_dec($c,$x) if _acmp($c,$y,_mul($c,_copy($c,$x),$x)) < 0; # overshot?
@@ -1556,7 +1566,7 @@ sub _root
# if $n is a power of two, we can repeatedly take sqrt($X) and find the
# proper result, because sqrt(sqrt($x)) == root($x,4)
my $b = _as_bin($c,$n);
- if ($$b =~ /0b1(0+)$/)
+ if ($b =~ /0b1(0+)$/)
{
my $count = CORE::length($1); # 0b100 => len('00') => 2
my $cnt = $count; # counter for loop
@@ -1658,13 +1668,13 @@ sub _and
($y1, $yr) = _div($c,$y1,$mask);
# make ints() from $xr, $yr
- # this is when the AND_BITS are greater tahn $BASE and is slower for
+ # this is when the AND_BITS are greater than $BASE and is slower for
# small (<256 bits) numbers, but faster for large numbers. Disabled
# due to KISS principle
# $b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; }
# $b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; }
-# _add($c,$x, _mul($c, _new( $c, \($xrr & $yrr) ), $m) );
+# _add($c,$x, _mul($c, _new( $c, ($xrr & $yrr) ), $m) );
# 0+ due to '&' doesn't work in strings
_add($c,$x, _mul($c, [ 0+$xr->[0] & 0+$yr->[0] ], $m) );
@@ -1694,7 +1704,7 @@ sub _xor
# make ints() from $xr, $yr (see _and())
#$b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; }
#$b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; }
- #_add($c,$x, _mul($c, _new( $c, \($xrr ^ $yrr) ), $m) );
+ #_add($c,$x, _mul($c, _new( $c, ($xrr ^ $yrr) ), $m) );
# 0+ due to '^' doesn't work in strings
_add($c,$x, _mul($c, [ 0+$xr->[0] ^ 0+$yr->[0] ], $m) );
@@ -1730,7 +1740,7 @@ sub _or
# make ints() from $xr, $yr (see _and())
# $b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; }
# $b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; }
-# _add($c,$x, _mul($c, _new( $c, \($xrr | $yrr) ), $m) );
+# _add($c,$x, _mul($c, _new( $c, ($xrr | $yrr) ), $m) );
# 0+ due to '|' doesn't work in strings
_add($c,$x, _mul($c, [ 0+$xr->[0] | 0+$yr->[0] ], $m) );
@@ -1754,7 +1764,7 @@ sub _as_hex
if (@$x == 1)
{
my $t = sprintf("0x%x",$x->[0]);
- return \$t;
+ return $t;
}
my $x1 = _copy($c,$x);
@@ -1778,7 +1788,7 @@ sub _as_hex
$es = reverse $es;
$es =~ s/^[0]+//; # strip leading zeros
$es = '0x' . $es;
- \$es;
+ $es;
}
sub _as_bin
@@ -1790,12 +1800,12 @@ sub _as_bin
# handle zero case for older Perls
if ($] <= 5.005 && @$x == 1 && $x->[0] == 0)
{
- my $t = '0b0'; return \$t;
+ my $t = '0b0'; return $t;
}
if (@$x == 1 && $] >= 5.006)
{
my $t = sprintf("0b%b",$x->[0]);
- return \$t;
+ return $t;
}
my $x1 = _copy($c,$x);
@@ -1819,7 +1829,7 @@ sub _as_bin
$es = reverse $es;
$es =~ s/^[0]+//; # strip leading zeros
$es = '0b' . $es;
- \$es;
+ $es;
}
sub _from_hex
@@ -1831,12 +1841,12 @@ sub _from_hex
my $m = [ 0x10000 ]; # 16 bit at a time
my $x = _zero();
- my $len = length($$hs)-2;
+ my $len = length($hs)-2;
$len = int($len/4); # 4-digit parts, w/o '0x'
my $val; my $i = -4;
while ($len >= 0)
{
- $val = substr($$hs,$i,4);
+ $val = substr($hs,$i,4);
$val =~ s/^[+-]?0x// if $len == 0; # for last part only because
$val = hex($val); # hex does not like wrong chars
$i -= 4; $len --;
@@ -1854,13 +1864,13 @@ sub _from_bin
# instead of converting X (8) bit at a time, it is faster to "convert" the
# number to hex, and then call _from_hex.
- my $hs = $$bs;
+ my $hs = $bs;
$hs =~ s/^[+-]?0b//; # remove sign and 0b
my $l = length($hs); # bits
$hs = '0' x (8-($l % 8)) . $hs if ($l % 8) != 0; # padd left side w/ 0
my $h = unpack('H*', pack ('B*', $hs)); # repack as hex
- $c->_from_hex(\('0x'.$h));
+ $c->_from_hex('0x'.$h);
}
##############################################################################
@@ -1918,7 +1928,7 @@ sub _modpow
my $acc = _copy($c,$num); my $t = _one();
- my $expbin = ${_as_bin($c,$exp)}; $expbin =~ s/^0b//;
+ my $expbin = _as_bin($c,$exp); $expbin =~ s/^0b//;
my $len = length($expbin);
while (--$len >= 0)
{
@@ -1934,6 +1944,20 @@ sub _modpow
$num;
}
+sub _gcd
+ {
+ # greatest common divisor
+ my ($c,$x,$y) = @_;
+
+ while (! _is_zero($c,$y))
+ {
+ my $t = _copy($c,$y);
+ $y = _mod($c, $x, $y);
+ $x = $t;
+ }
+ $x;
+ }
+
##############################################################################
##############################################################################
@@ -1966,11 +1990,14 @@ version like 'Pari'.
=head1 METHODS
The following functions MUST be defined in order to support the use by
-Math::BigInt:
+Math::BigInt v1.70 or later:
+ api_version() return API version, minimum 1 for v1.70
_new(string) return ref to new object from ref to decimal string
_zero() return a new object with value 0
_one() return a new object with value 1
+ _two() return a new object with value 2
+ _ten() return a new object with value 10
_str(obj) return ref to a string representing the object
_num(obj) returns a Perl integer/floating point number
@@ -2000,7 +2027,9 @@ Math::BigInt:
_len(obj) returns count of the decimal digits of the object
_digit(obj,n) returns the n'th decimal digit of object
- _is_one(obj) return true if argument is +1
+ _is_one(obj) return true if argument is 1
+ _is_two(obj) return true if argument is 2
+ _is_ten(obj) return true if argument is 10
_is_zero(obj) return true if argument is 0
_is_even(obj) return true if argument is even (0,2,4,6..)
_is_odd(obj) return true if argument is odd (1,3,5,7..)
@@ -2010,14 +2039,10 @@ Math::BigInt:
_check(obj) check whether internal representation is still intact
return 0 for ok, otherwise error message as string
-The following functions are optional, and can be defined if the underlying lib
-has a fast way to do them. If undefined, Math::BigInt will use pure Perl (hence
-slow) fallback routines to emulate these:
-
_from_hex(str) return ref to new object from ref to hexadecimal string
_from_bin(str) return ref to new object from ref to binary string
- _as_hex(str) return ref to scalar string containing the value as
+ _as_hex(str) return string containing the value as
unsigned hex string, with the '0x' prepended.
Leading zeros must be stripped.
_as_bin(str) Like as_hex, only as binary string containing only
@@ -2025,27 +2050,19 @@ slow) fallback routines to emulate these:
'0b' must be prepended.
_rsft(obj,N,B) shift object in base B by N 'digits' right
- For unsupported bases B, return undef to signal failure
_lsft(obj,N,B) shift object in base B by N 'digits' left
- For unsupported bases B, return undef to signal failure
_xor(obj1,obj2) XOR (bit-wise) object 1 with object 2
Note: XOR, AND and OR pad with zeros if size mismatches
_and(obj1,obj2) AND (bit-wise) object 1 with object 2
_or(obj1,obj2) OR (bit-wise) object 1 with object 2
- _signed_or
- _signed_and
- _signed_xor
-
_mod(obj,obj) Return remainder of div of the 1st by the 2nd object
_sqrt(obj) return the square root of object (truncated to int)
_root(obj) return the n'th (n >= 3) root of obj (truncated to int)
_fac(obj) return factorial of object 1 (1*2*3*4..)
_pow(obj,obj) return object 1 to the power of object 2
return undef for NaN
- _gcd(obj,obj) return Greatest Common Divisor of two objects
-
_zeros(obj) return number of trailing decimal zeros
_modinv return inverse modulus
_modpow return modulus of power ($x ** $y) % $z
@@ -2055,6 +2072,16 @@ slow) fallback routines to emulate these:
1 : result is exactly RESULT
0 : result was truncated to RESULT
undef : unknown whether result is exactly RESULT
+ _gcd(obj,obj) return Greatest Common Divisor of two objects
+
+The following functions are optional, and can be defined if the underlying lib
+has a fast way to do them. If undefined, Math::BigInt will use pure Perl (hence
+slow) fallback routines to emulate these:
+
+ _signed_or
+ _signed_and
+ _signed_xor
+
Input strings come in as unsigned but with prefix (i.e. as '123', '0xabc'
or '0b1101').
@@ -2072,11 +2099,6 @@ returning a different reference.
Return values are always references to objects, strings, or true/false for
comparisation routines.
-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
-the one you can support back to Math::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
@@ -2103,6 +2125,7 @@ Original math code by Mark Biggar, rewritten by Tels L<http://bloodgate.com/>
in late 2000.
Seperated from BigInt and shaped API with the help of John Peacock.
Fixed, sped-up and enhanced by Tels http://bloodgate.com 2001-2003.
+Further streamlining (api_version 1) by Tels 2004.
=head1 SEE ALSO
diff --git a/lib/Math/BigInt/CalcEmu.pm b/lib/Math/BigInt/CalcEmu.pm
index c95b32fb3b..9f7fd16434 100644
--- a/lib/Math/BigInt/CalcEmu.pm
+++ b/lib/Math/BigInt/CalcEmu.pm
@@ -5,7 +5,7 @@ use strict;
# use warnings; # dont use warnings for older Perls
use vars qw/$VERSION/;
-$VERSION = '0.03';
+$VERSION = '0.04';
package Math::BigInt;
@@ -18,141 +18,6 @@ BEGIN
$CALC_EMU = Math::BigInt->config()->{'lib'};
}
-sub __emu_blog
- {
- my ($self,$x,$base,@r) = @_;
-
- return $x->bnan() if $x->is_zero() || $base->is_zero() || $base->is_one();
-
- my $acmp = $x->bacmp($base);
- return $x->bone('+',@r) if $acmp == 0;
- return $x->bzero(@r) if $acmp < 0 || $x->is_one();
-
- # blog($x,$base) ** $base + $y = $x
-
- # this trial multiplication is very fast, even for large counts (like for
- # 2 ** 1024, since this still requires only 1024 very fast steps
- # (multiplication of a large number by a very small number is very fast))
- # See Calc for an even faster algorightmn
- my $x_org = $x->copy(); # preserve orgx
- $x->bzero(); # keep ref to $x
- my $trial = $base->copy();
- while ($trial->bacmp($x_org) <= 0)
- {
- $trial->bmul($base); $x->binc();
- }
- $x->round(@r);
- }
-
-sub __emu_bmodinv
- {
- my ($self,$x,$y,@r) = @_;
-
- my ($u, $u1) = ($self->bzero(), $self->bone());
- my ($a, $b) = ($y->copy(), $x->copy());
-
- # first step need always be done since $num (and thus $b) is never 0
- # Note that the loop is aligned so that the check occurs between #2 and #1
- # thus saving us one step #2 at the loop end. Typical loop count is 1. Even
- # a case with 28 loops still gains about 3% with this layout.
- my $q;
- ($a, $q, $b) = ($b, $a->bdiv($b)); # step #1
- # Euclid's Algorithm (calculate GCD of ($a,$b) in $a and also calculate
- # two values in $u and $u1, we use only $u1 afterwards)
- my $sign = 1; # flip-flop
- while (!$b->is_zero()) # found GCD if $b == 0
- {
- # the original algorithm had:
- # ($u, $u1) = ($u1, $u->bsub($u1->copy()->bmul($q))); # step #2
- # The following creates exact the same sequence of numbers in $u1,
- # except for the sign ($u1 is now always positive). Since formerly
- # the sign of $u1 was alternating between '-' and '+', the $sign
- # flip-flop will take care of that, so that at the end of the loop
- # we have the real sign of $u1. Keeping numbers positive gains us
- # speed since badd() is faster than bsub() and makes it possible
- # to have the algorithmn in Calc for even more speed.
-
- ($u, $u1) = ($u1, $u->badd($u1->copy()->bmul($q))); # step #2
- $sign = - $sign; # flip sign
-
- ($a, $q, $b) = ($b, $a->bdiv($b)); # step #1 again
- }
-
- # If the gcd is not 1, then return NaN! It would be pointless to have
- # called bgcd to check this first, because we would then be performing
- # the same Euclidean Algorithm *twice* in case the gcd is 1.
- return $x->bnan() unless $a->is_one();
-
- $u1->bneg() if $sign != 1; # need to flip?
-
- $u1->bmod($y); # calc result
- $x->{value} = $u1->{value}; # and copy over to $x
- $x->{sign} = $u1->{sign}; # to modify in place
- $x->round(@r);
- }
-
-sub __emu_bmodpow
- {
- my ($self,$num,$exp,$mod,@r) = @_;
-
- # in the trivial case,
- return $num->bzero(@r) if $mod->is_one();
- return $num->bone('+',@r) if $num->is_zero() or $num->is_one();
-
- # $num->bmod($mod); # if $x is large, make it smaller first
- my $acc = $num->copy(); # but this is not really faster...
-
- $num->bone(); # keep ref to $num
-
- my $expbin = $exp->as_bin(); $expbin =~ s/^[-]?0b//; # ignore sign and prefix
- my $len = CORE::length($expbin);
- while (--$len >= 0)
- {
- $num->bmul($acc)->bmod($mod) if substr($expbin,$len,1) eq '1';
- $acc->bmul($acc)->bmod($mod);
- }
-
- $num->round(@r);
- }
-
-sub __emu_bfac
- {
- my ($self,$x,@r) = @_;
-
- return $x->bone('+',@r) if $x->is_zero() || $x->is_one(); # 0 or 1 => 1
-
- my $n = $x->copy();
- $x->bone();
- # seems we need not to temp. clear A/P of $x since the result is the same
- my $f = $self->new(2);
- while ($f->bacmp($n) < 0)
- {
- $x->bmul($f); $f->binc();
- }
- $x->bmul($f,@r); # last step and also round result
- }
-
-sub __emu_bpow
- {
- my ($self,$x,$y,@r) = @_;
-
- return $x->bone('+',@r) if $y->is_zero();
- return $x->round(@r) if $x->is_one() || $y->is_one();
- return $x->round(@r) if $x->is_zero(); # 0**y => 0 (if not y <= 0)
-
- my $pow2 = $self->bone();
- my $y_bin = $y->as_bin(); $y_bin =~ s/^0b//;
- my $len = CORE::length($y_bin);
- while (--$len > 0)
- {
- $pow2->bmul($x) if substr($y_bin,$len,1) eq '1'; # is odd?
- $x->bmul($x);
- }
- $x->bmul($pow2);
- $x->round(@r) if !exists $x->{_f} || $x->{_f} & MB_NEVER_ROUND == 0;
- $x;
- }
-
sub __emu_band
{
my ($self,$x,$y,$sx,$sy,@r) = @_;
@@ -194,26 +59,29 @@ sub __emu_band
$bx = reverse $bx;
$by = reverse $by;
- # cut the longer string to the length of the shorter one (the result would
- # be 0 due to AND anyway)
+ # padd the shorter string
+ my $xx = "\x00"; $xx = "\x0f" if $sx == -1;
+ my $yy = "\x00"; $yy = "\x0f" if $sy == -1;
my $diff = CORE::length($bx) - CORE::length($by);
if ($diff > 0)
{
- $bx = substr($bx,0,CORE::length($by));
+ # if $yy eq "\x00", we can cut $bx, otherwise we need to padd $by
+ $by .= $yy x $diff;
}
elsif ($diff < 0)
{
- $by = substr($by,0,CORE::length($bx));
+ # if $xx eq "\x00", we can cut $by, otherwise we need to padd $bx
+ $bx .= $xx x abs($diff);
}
-
+
# and the strings together
my $r = $bx & $by;
# and reverse the result again
$bx = reverse $r;
- # one of $x or $y was negative, so need to flip bits in the result
- # in both cases (one or two of them negative, or both positive) we need
+ # One of $x or $y was negative, so need to flip bits in the result.
+ # In both cases (one or two of them negative, or both positive) we need
# to get the characters back.
if ($sign == 1)
{
@@ -224,20 +92,12 @@ sub __emu_band
$bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
}
+ # leading zeros will be stripped by _from_hex()
$bx = '0x' . $bx;
- if ($CALC_EMU->can('_from_hex'))
- {
- $x->{value} = $CALC_EMU->_from_hex( \$bx );
- }
- else
- {
- $r = $self->new($bx);
- $x->{value} = $r->{value};
- }
+ $x->{value} = $CALC_EMU->_from_hex( $bx );
# calculate sign of result
$x->{sign} = '+';
- #$x->{sign} = '-' if $sx == $sy && $sx == -1 && !$x->is_zero();
$x->{sign} = '-' if $sign == 1 && !$x->is_zero();
$x->bdec() if $sign == 1;
@@ -317,16 +177,13 @@ sub __emu_bior
$bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
}
+ # leading zeros will be stripped by _from_hex()
$bx = '0x' . $bx;
- if ($CALC_EMU->can('_from_hex'))
- {
- $x->{value} = $CALC_EMU->_from_hex( \$bx );
- }
- else
- {
- $r = $self->new($bx);
- $x->{value} = $r->{value};
- }
+ $x->{value} = $CALC_EMU->_from_hex( $bx );
+
+ # calculate sign of result
+ $x->{sign} = '+';
+ $x->{sign} = '-' if $sign == 1 && !$x->is_zero();
# if one of X or Y was negative, we need to decrement result
$x->bdec() if $sign == 1;
@@ -406,16 +263,9 @@ sub __emu_bxor
$bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
}
+ # leading zeros will be stripped by _from_hex()
$bx = '0x' . $bx;
- if ($CALC_EMU->can('_from_hex'))
- {
- $x->{value} = $CALC_EMU->_from_hex( \$bx );
- }
- else
- {
- $r = $self->new($bx);
- $x->{value} = $r->{value};
- }
+ $x->{value} = $CALC_EMU->_from_hex( $bx );
# calculate sign of result
$x->{sign} = '+';
@@ -426,170 +276,6 @@ sub __emu_bxor
$x->round(@r);
}
-sub __emu_bsqrt
- {
- my ($self,$x,@r) = @_;
-
- # this is slow:
- return $x->round(@r) if $x->is_zero(); # 0,1 => 0,1
-
- return $x->bone('+',@r) if $x < 4; # 1,2,3 => 1
- my $y = $x->copy();
- my $l = int($x->length()/2);
-
- $x->bone(); # keep ref($x), but modify it
- $x->blsft($l,10) if $l != 0; # first guess: 1.('0' x (l/2))
-
- my $last = $self->bzero();
- my $two = $self->new(2);
- my $lastlast = $self->bzero();
- #my $lastlast = $x+$two;
- while ($last != $x && $lastlast != $x)
- {
- $lastlast = $last; $last = $x->copy();
- $x->badd($y / $x);
- $x->bdiv($two);
- }
- $x->bdec() if $x * $x > $y; # overshot?
- $x->round(@r);
- }
-
-sub __emu_broot
- {
- my ($self,$x,$y,@r) = @_;
-
- return $x->bsqrt() if $y->bacmp(2) == 0; # 2 => square root
-
- # since we take at least a cubic root, and only 8 ** 1/3 >= 2 (==2):
- return $x->bone('+',@r) if $x < 8; # $x=2..7 => 1
-
- my $num = $x->numify();
-
- if ($num <= 1000000)
- {
- $x = $self->new( int ( sprintf ("%.8f", $num ** (1 / $y->numify() ))));
- return $x->round(@r);
- }
-
- # if $n is a power of two, we can repeatedly take sqrt($X) and find the
- # proper result, because sqrt(sqrt($x)) == root($x,4)
- # See Calc.pm for more details
- my $b = $y->as_bin();
- if ($b =~ /0b1(0+)$/)
- {
- my $count = CORE::length($1); # 0b100 => len('00') => 2
- my $cnt = $count; # counter for loop
- my $shift = $self->new(6);
- $x->blsft($shift); # add some zeros (even amount)
- while ($cnt-- > 0)
- {
- # 'inflate' $X by adding more zeros
- $x->blsft($shift);
- # calculate sqrt($x), $x is now a bit too big, again. In the next
- # round we make even bigger, again.
- $x->bsqrt($x);
- }
- # $x is still to big, so truncate result
- $x->brsft($shift);
- }
- else
- {
- # trial computation by starting with 2,4,6,8,10 etc until we overstep
- my $step;
- my $trial = $self->new(2);
- my $two = $self->new(2);
- my $s_128 = $self->new(128);
-
- local undef $Math::BigInt::accuracy;
- local undef $Math::BigInt::precision;
-
- # while still to do more than X steps
- do
- {
- $step = $self->new(2);
- while ( $trial->copy->bpow($y)->bacmp($x) < 0)
- {
- $step->bmul($two);
- $trial->badd($step);
- }
-
- # hit exactly?
- if ( $trial->copy->bpow($y)->bacmp($x) == 0)
- {
- $x->{value} = $trial->{value}; # make copy while preserving ref to $x
- return $x->round(@r);
- }
- # overstepped, so go back on step
- $trial->bsub($step);
- } while ($step > $s_128);
-
- $step = $two->copy();
- while ( $trial->copy->bpow($y)->bacmp($x) < 0)
- {
- $trial->badd($step);
- }
-
- # not hit exactly?
- if ( $x->bacmp( $trial->copy()->bpow($y) ) < 0)
- {
- $trial->bdec();
- }
- # copy result into $x (preserve ref)
- $x->{value} = $trial->{value};
- }
- $x->round(@r);
- }
-
-sub __emu_as_hex
- {
- my ($self,$x,$s) = @_;
-
- return '0x0' if $x->is_zero();
-
- my $x1 = $x->copy()->babs(); my ($xr,$x10000,$h,$es);
- if ($] >= 5.006)
- {
- $x10000 = $self->new (0x10000); $h = 'h4';
- }
- else
- {
- $x10000 = $self->new (0x1000); $h = 'h3';
- }
- while (!$x1->is_zero())
- {
- ($x1, $xr) = bdiv($x1,$x10000);
- $es .= unpack($h,pack('v',$xr->numify()));
- }
- $es = reverse $es;
- $es =~ s/^[0]+//; # strip leading zeros
- $s . '0x' . $es;
- }
-
-sub __emu_as_bin
- {
- my ($self,$x,$s) = @_;
-
- return '0b0' if $x->is_zero();
-
- my $x1 = $x->copy()->babs(); my ($xr,$x10000,$b,$es);
- if ($] >= 5.006)
- {
- $x10000 = $self->new (0x10000); $b = 'b16';
- }
- else
- {
- $x10000 = $self->new (0x1000); $b = 'b12';
- }
- while (!$x1->is_zero())
- {
- ($x1, $xr) = bdiv($x1,$x10000);
- $es .= unpack($b,pack('v',$xr->numify()));
- }
- $es = reverse $es;
- $es =~ s/^[0]+//; # strip leading zeros
- $s . '0b' . $es;
- }
-
##############################################################################
##############################################################################
@@ -622,7 +308,7 @@ the same terms as Perl itself.
=head1 AUTHORS
-(c) Tels http://bloodgate.com 2003 - based on BigInt code by
+(c) Tels http://bloodgate.com 2003, 2004 - based on BigInt code by
Tels from 2001-2003.
=head1 SEE ALSO
diff --git a/lib/Math/BigInt/t/bare_mbf.t b/lib/Math/BigInt/t/bare_mbf.t
index 08ac4c2ad4..9f946717d2 100644
--- a/lib/Math/BigInt/t/bare_mbf.t
+++ b/lib/Math/BigInt/t/bare_mbf.t
@@ -27,7 +27,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 1772;
+ plan tests => 1814;
}
use Math::BigFloat lib => 'BareCalc';
diff --git a/lib/Math/BigInt/t/bare_mbi.t b/lib/Math/BigInt/t/bare_mbi.t
index 0cc055e2c2..6514e1ec43 100644
--- a/lib/Math/BigInt/t/bare_mbi.t
+++ b/lib/Math/BigInt/t/bare_mbi.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 2770;
+ plan tests => 2832;
}
use Math::BigInt lib => 'BareCalc';
diff --git a/lib/Math/BigInt/t/bare_mif.t b/lib/Math/BigInt/t/bare_mif.t
index 00629fd9a5..0cc1de9365 100644
--- a/lib/Math/BigInt/t/bare_mif.t
+++ b/lib/Math/BigInt/t/bare_mif.t
@@ -28,7 +28,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 679
+ plan tests => 684
+ 1; # our own tests
}
diff --git a/lib/Math/BigInt/t/bigfltpm.inc b/lib/Math/BigInt/t/bigfltpm.inc
index 34d264a911..d307ee6a27 100644
--- a/lib/Math/BigInt/t/bigfltpm.inc
+++ b/lib/Math/BigInt/t/bigfltpm.inc
@@ -30,7 +30,7 @@ while (<DATA>)
{
@args = split(/:/,$_,99); $ans = pop(@args);
}
- $try = "\$x = $class->new('$args[0]');";
+ $try = "\$x = $class->new(\"$args[0]\");";
if ($f eq "fnorm")
{
$try .= "\$x;";
@@ -142,7 +142,7 @@ while (<DATA>)
# trailing zeros
#print $ans1->_trailing_zeros(),"\n";
print "# Has trailing zeros after '$try'\n"
- if !ok ($ans1->{_m}->_trailing_zeros(), 0);
+ if !ok ($CL->_zeros( $ans1->{_m}), 0);
}
}
} # end pattern or string
@@ -165,9 +165,11 @@ ok ($y,1200); ok ($x,1200);
my $monster = '1e1234567890123456789012345678901234567890';
-# new
+# new and exponent
ok ($class->new($monster)->bsstr(),
'1e+1234567890123456789012345678901234567890');
+ok ($class->new($monster)->exponent(),
+ '1234567890123456789012345678901234567890');
# cmp
ok ($class->new($monster) > 0,1);
@@ -176,6 +178,11 @@ ok ($class->new($monster)->bsub( $monster),0);
ok ($class->new($monster)->bmul(2)->bsstr(),
'2e+1234567890123456789012345678901234567890');
+# mantissa
+$monster = '1234567890123456789012345678901234567890e2';
+ok ($class->new($monster)->mantissa(),
+ '123456789012345678901234567890123456789');
+
###############################################################################
# zero,inf,one,nan
@@ -476,6 +483,18 @@ abc:NaN
-3e111:-3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-4e-1111:-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
&fpow
+NaN:1:NaN
+1:NaN:NaN
+NaN:-1:NaN
+-1:NaN:NaN
+NaN:-21:NaN
+-21:NaN:NaN
+NaN:21:NaN
+21:NaN:NaN
+0:0:1
+0:1:0
+0:9:0
+0:-2:inf
2:2:4
1:2:1
1:3:1
@@ -491,6 +510,14 @@ abc:123.456:NaN
-inf:123.45:-inf
+inf:-123.45:inf
-inf:-123.45:-inf
+-2:2:4
+-2:3:-8
+-2:4:16
+-2:5:-32
+-3:2:9
+-3:3:-27
+-3:4:81
+-3:5:-243
# 2 ** 0.5 == sqrt(2)
# 1.41..7 and not 1.4170 since fallback (bsqrt(9) is '3', not 3.0...0)
2:0.5:1.41421356237309504880168872420969807857
diff --git a/lib/Math/BigInt/t/bigfltpm.t b/lib/Math/BigInt/t/bigfltpm.t
index 84741bad23..3fce4605b3 100755
--- a/lib/Math/BigInt/t/bigfltpm.t
+++ b/lib/Math/BigInt/t/bigfltpm.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 1772
+ plan tests => 1814
+ 2; # own tests
}
@@ -38,6 +38,6 @@ $class = "Math::BigFloat";
$CL = "Math::BigInt::Calc";
ok ($class->config()->{class},$class);
-ok ($class->config()->{with},'Math::BigInt');
+ok ($class->config()->{with}, $CL);
require 'bigfltpm.inc'; # all tests here for sharing
diff --git a/lib/Math/BigInt/t/bigintc.t b/lib/Math/BigInt/t/bigintc.t
index 1f0804cf9c..f0aa66dea0 100644
--- a/lib/Math/BigInt/t/bigintc.t
+++ b/lib/Math/BigInt/t/bigintc.t
@@ -8,15 +8,11 @@ BEGIN
$| = 1;
chdir 't' if -d 't';
unshift @INC, '../lib'; # for running manually
+ plan tests => 308;
}
use Math::BigInt::Calc;
-BEGIN
- {
- plan tests => 300;
- }
-
my ($BASE_LEN, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN_SMALL, $MAX_VAL) =
Math::BigInt::Calc->_base_len();
@@ -31,52 +27,59 @@ print "# IOR_BITS = $OR_BITS\n";
my $C = 'Math::BigInt::Calc'; # pass classname to sub's
# _new and _str
-my $x = $C->_new(\"123"); my $y = $C->_new(\"321");
-ok (ref($x),'ARRAY'); ok (${$C->_str($x)},123); ok (${$C->_str($y)},321);
+my $x = $C->_new("123"); my $y = $C->_new("321");
+ok (ref($x),'ARRAY'); ok ($C->_str($x),123); ok ($C->_str($y),321);
###############################################################################
# _add, _sub, _mul, _div
-ok (${$C->_str($C->_add($x,$y))},444);
-ok (${$C->_str($C->_sub($x,$y))},123);
-ok (${$C->_str($C->_mul($x,$y))},39483);
-ok (${$C->_str($C->_div($x,$y))},123);
+ok ($C->_str($C->_add($x,$y)),444);
+ok ($C->_str($C->_sub($x,$y)),123);
+ok ($C->_str($C->_mul($x,$y)),39483);
+ok ($C->_str($C->_div($x,$y)),123);
###############################################################################
# check that mul/div doesn't change $y
# and returns the same reference, not something new
-ok (${$C->_str($C->_mul($x,$y))},39483);
-ok (${$C->_str($x)},39483); ok (${$C->_str($y)},321);
+ok ($C->_str($C->_mul($x,$y)),39483);
+ok ($C->_str($x),39483); ok ($C->_str($y),321);
-ok (${$C->_str($C->_div($x,$y))},123);
-ok (${$C->_str($x)},123); ok (${$C->_str($y)},321);
+ok ($C->_str($C->_div($x,$y)),123);
+ok ($C->_str($x),123); ok ($C->_str($y),321);
-$x = $C->_new(\"39483");
+$x = $C->_new("39483");
my ($x1,$r1) = $C->_div($x,$y);
ok ("$x1","$x");
$C->_inc($x1);
ok ("$x1","$x");
-ok (${$C->_str($r1)},'0');
+ok ($C->_str($r1),'0');
-$x = $C->_new(\"39483"); # reset
+$x = $C->_new("39483"); # reset
###############################################################################
-my $z = $C->_new(\"2");
-ok (${$C->_str($C->_add($x,$z))},39485);
+my $z = $C->_new("2");
+ok ($C->_str($C->_add($x,$z)),39485);
my ($re,$rr) = $C->_div($x,$y);
-ok (${$C->_str($re)},123); ok (${$C->_str($rr)},2);
+ok ($C->_str($re),123); ok ($C->_str($rr),2);
# is_zero, _is_one, _one, _zero
ok ($C->_is_zero($x)||0,0);
ok ($C->_is_one($x)||0,0);
-ok (${$C->_str($C->_zero())},"0");
-ok (${$C->_str($C->_one())},"1");
+ok ($C->_str($C->_zero()),"0");
+ok ($C->_str($C->_one()),"1");
-# _two() (only used internally)
-ok (${$C->_str($C->_two())},"2");
+# _two() and _ten()
+ok ($C->_str($C->_two()),"2");
+ok ($C->_str($C->_ten()),"10");
+ok ($C->_is_ten($C->_two()),0);
+ok ($C->_is_two($C->_two()),1);
+ok ($C->_is_ten($C->_ten()),1);
+ok ($C->_is_two($C->_ten()),0);
ok ($C->_is_one($C->_one()),1);
+ok ($C->_is_one($C->_two()),0);
+ok ($C->_is_one($C->_ten()),0);
ok ($C->_is_one($C->_zero()) || 0,0);
@@ -89,35 +92,35 @@ ok ($C->_is_odd($C->_one()),1); ok ($C->_is_odd($C->_zero())||0,0);
ok ($C->_is_even($C->_one()) || 0,0); ok ($C->_is_even($C->_zero()),1);
# _len
-$x = $C->_new(\"1"); ok ($C->_len($x),1);
-$x = $C->_new(\"12"); ok ($C->_len($x),2);
-$x = $C->_new(\"123"); ok ($C->_len($x),3);
-$x = $C->_new(\"1234"); ok ($C->_len($x),4);
-$x = $C->_new(\"12345"); ok ($C->_len($x),5);
-$x = $C->_new(\"123456"); ok ($C->_len($x),6);
-$x = $C->_new(\"1234567"); ok ($C->_len($x),7);
-$x = $C->_new(\"12345678"); ok ($C->_len($x),8);
-$x = $C->_new(\"123456789"); ok ($C->_len($x),9);
-
-$x = $C->_new(\"8"); ok ($C->_len($x),1);
-$x = $C->_new(\"21"); ok ($C->_len($x),2);
-$x = $C->_new(\"321"); ok ($C->_len($x),3);
-$x = $C->_new(\"4321"); ok ($C->_len($x),4);
-$x = $C->_new(\"54321"); ok ($C->_len($x),5);
-$x = $C->_new(\"654321"); ok ($C->_len($x),6);
-$x = $C->_new(\"7654321"); ok ($C->_len($x),7);
-$x = $C->_new(\"87654321"); ok ($C->_len($x),8);
-$x = $C->_new(\"987654321"); ok ($C->_len($x),9);
+$x = $C->_new("1"); ok ($C->_len($x),1);
+$x = $C->_new("12"); ok ($C->_len($x),2);
+$x = $C->_new("123"); ok ($C->_len($x),3);
+$x = $C->_new("1234"); ok ($C->_len($x),4);
+$x = $C->_new("12345"); ok ($C->_len($x),5);
+$x = $C->_new("123456"); ok ($C->_len($x),6);
+$x = $C->_new("1234567"); ok ($C->_len($x),7);
+$x = $C->_new("12345678"); ok ($C->_len($x),8);
+$x = $C->_new("123456789"); ok ($C->_len($x),9);
+
+$x = $C->_new("8"); ok ($C->_len($x),1);
+$x = $C->_new("21"); ok ($C->_len($x),2);
+$x = $C->_new("321"); ok ($C->_len($x),3);
+$x = $C->_new("4321"); ok ($C->_len($x),4);
+$x = $C->_new("54321"); ok ($C->_len($x),5);
+$x = $C->_new("654321"); ok ($C->_len($x),6);
+$x = $C->_new("7654321"); ok ($C->_len($x),7);
+$x = $C->_new("87654321"); ok ($C->_len($x),8);
+$x = $C->_new("987654321"); ok ($C->_len($x),9);
for (my $i = 1; $i < 9; $i++)
{
my $a = "$i" . '0' x ($i-1);
- $x = $C->_new(\$a);
+ $x = $C->_new($a);
print "# Tried len '$a'\n" unless ok ($C->_len($x),$i);
}
# _digit
-$x = $C->_new(\"123456789");
+$x = $C->_new("123456789");
ok ($C->_digit($x,0),9);
ok ($C->_digit($x,1),8);
ok ($C->_digit($x,2),7);
@@ -128,201 +131,202 @@ ok ($C->_digit($x,-3),3);
# _copy
foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/)
{
- $x = $C->_new(\"$_");
- ok (${$C->_str($C->_copy($x))},"$_");
- ok (${$C->_str($x)},"$_"); # did _copy destroy original x?
+ $x = $C->_new("$_");
+ ok ($C->_str($C->_copy($x)),"$_");
+ ok ($C->_str($x),"$_"); # did _copy destroy original x?
}
# _zeros
-$x = $C->_new(\"1256000000"); ok ($C->_zeros($x),6);
-$x = $C->_new(\"152"); ok ($C->_zeros($x),0);
-$x = $C->_new(\"123000"); ok ($C->_zeros($x),3);
+$x = $C->_new("1256000000"); ok ($C->_zeros($x),6);
+$x = $C->_new("152"); ok ($C->_zeros($x),0);
+$x = $C->_new("123000"); ok ($C->_zeros($x),3);
+$x = $C->_new("0"); ok ($C->_zeros($x),0);
# _lsft, _rsft
-$x = $C->_new(\"10"); $y = $C->_new(\"3");
-ok (${$C->_str($C->_lsft($x,$y,10))},10000);
-$x = $C->_new(\"20"); $y = $C->_new(\"3");
-ok (${$C->_str($C->_lsft($x,$y,10))},20000);
+$x = $C->_new("10"); $y = $C->_new("3");
+ok ($C->_str($C->_lsft($x,$y,10)),10000);
+$x = $C->_new("20"); $y = $C->_new("3");
+ok ($C->_str($C->_lsft($x,$y,10)),20000);
-$x = $C->_new(\"128"); $y = $C->_new(\"4");
-ok (${$C->_str($C->_lsft($x,$y,2))}, 128 << 4);
+$x = $C->_new("128"); $y = $C->_new("4");
+ok ($C->_str($C->_lsft($x,$y,2)), 128 << 4);
-$x = $C->_new(\"1000"); $y = $C->_new(\"3");
-ok (${$C->_str($C->_rsft($x,$y,10))},1);
-$x = $C->_new(\"20000"); $y = $C->_new(\"3");
-ok (${$C->_str($C->_rsft($x,$y,10))},20);
-$x = $C->_new(\"256"); $y = $C->_new(\"4");
-ok (${$C->_str($C->_rsft($x,$y,2))},256 >> 4);
+$x = $C->_new("1000"); $y = $C->_new("3");
+ok ($C->_str($C->_rsft($x,$y,10)),1);
+$x = $C->_new("20000"); $y = $C->_new("3");
+ok ($C->_str($C->_rsft($x,$y,10)),20);
+$x = $C->_new("256"); $y = $C->_new("4");
+ok ($C->_str($C->_rsft($x,$y,2)),256 >> 4);
-$x = $C->_new(\"6411906467305339182857313397200584952398");
-$y = $C->_new(\"45");
-ok (${$C->_str($C->_rsft($x,$y,10))},0);
+$x = $C->_new("6411906467305339182857313397200584952398");
+$y = $C->_new("45");
+ok ($C->_str($C->_rsft($x,$y,10)),0);
# _acmp
-$x = $C->_new(\"123456789");
-$y = $C->_new(\"987654321");
+$x = $C->_new("123456789");
+$y = $C->_new("987654321");
ok ($C->_acmp($x,$y),-1);
ok ($C->_acmp($y,$x),1);
ok ($C->_acmp($x,$x),0);
ok ($C->_acmp($y,$y),0);
-$x = $C->_new(\"12");
-$y = $C->_new(\"12");
+$x = $C->_new("12");
+$y = $C->_new("12");
ok ($C->_acmp($x,$y),0);
-$x = $C->_new(\"21");
+$x = $C->_new("21");
ok ($C->_acmp($x,$y),1);
ok ($C->_acmp($y,$x),-1);
-$x = $C->_new(\"123456789");
-$y = $C->_new(\"1987654321");
+$x = $C->_new("123456789");
+$y = $C->_new("1987654321");
ok ($C->_acmp($x,$y),-1);
ok ($C->_acmp($y,$x),+1);
-$x = $C->_new(\"1234567890123456789");
-$y = $C->_new(\"987654321012345678");
+$x = $C->_new("1234567890123456789");
+$y = $C->_new("987654321012345678");
ok ($C->_acmp($x,$y),1);
ok ($C->_acmp($y,$x),-1);
ok ($C->_acmp($x,$x),0);
ok ($C->_acmp($y,$y),0);
-$x = $C->_new(\"1234");
-$y = $C->_new(\"987654321012345678");
+$x = $C->_new("1234");
+$y = $C->_new("987654321012345678");
ok ($C->_acmp($x,$y),-1);
ok ($C->_acmp($y,$x),1);
ok ($C->_acmp($x,$x),0);
ok ($C->_acmp($y,$y),0);
# _modinv
-$x = $C->_new(\"8");
-$y = $C->_new(\"5033");
+$x = $C->_new("8");
+$y = $C->_new("5033");
my ($xmod,$sign) = $C->_modinv($x,$y);
-ok (${$C->_str($xmod)},'629'); # -629 % 5033 == 4404
+ok ($C->_str($xmod),'629'); # -629 % 5033 == 4404
ok ($sign, '-');
# _div
-$x = $C->_new(\"3333"); $y = $C->_new(\"1111");
-ok (${$C->_str(scalar $C->_div($x,$y))},3);
-$x = $C->_new(\"33333"); $y = $C->_new(\"1111"); ($x,$y) = $C->_div($x,$y);
-ok (${$C->_str($x)},30); ok (${$C->_str($y)},3);
-$x = $C->_new(\"123"); $y = $C->_new(\"1111");
-($x,$y) = $C->_div($x,$y); ok (${$C->_str($x)},0); ok (${$C->_str($y)},123);
+$x = $C->_new("3333"); $y = $C->_new("1111");
+ok ($C->_str(scalar $C->_div($x,$y)),3);
+$x = $C->_new("33333"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y);
+ok ($C->_str($x),30); ok ($C->_str($y),3);
+$x = $C->_new("123"); $y = $C->_new("1111");
+($x,$y) = $C->_div($x,$y); ok ($C->_str($x),0); ok ($C->_str($y),123);
# _num
foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/)
{
- $x = $C->_new(\"$_");
- ok (ref($x)||'','ARRAY'); ok (${$C->_str($x)},"$_");
+ $x = $C->_new("$_");
+ ok (ref($x)||'','ARRAY'); ok ($C->_str($x),"$_");
$x = $C->_num($x); ok (ref($x)||'',''); ok ($x,$_);
}
# _sqrt
-$x = $C->_new(\"144"); ok (${$C->_str($C->_sqrt($x))},'12');
-$x = $C->_new(\"144000000000000"); ok (${$C->_str($C->_sqrt($x))},'12000000');
+$x = $C->_new("144"); ok ($C->_str($C->_sqrt($x)),'12');
+$x = $C->_new("144000000000000"); ok ($C->_str($C->_sqrt($x)),'12000000');
# _root
-$x = $C->_new(\"81"); my $n = $C->_new(\"3"); # 4*4*4 = 64, 5*5*5 = 125
-ok (${$C->_str($C->_root($x,$n))},'4'); # 4.xx => 4.0
-$x = $C->_new(\"81"); $n = $C->_new(\"4"); # 3*3*3*3 == 81
-ok (${$C->_str($C->_root($x,$n))},'3');
+$x = $C->_new("81"); my $n = $C->_new("3"); # 4*4*4 = 64, 5*5*5 = 125
+ok ($C->_str($C->_root($x,$n)),'4'); # 4.xx => 4.0
+$x = $C->_new("81"); $n = $C->_new("4"); # 3*3*3*3 == 81
+ok ($C->_str($C->_root($x,$n)),'3');
# _pow (and _root)
-$x = $C->_new(\"0"); $n = $C->_new(\"3"); # 0 ** y => 0
-ok (${$C->_str($C->_pow($x,$n))}, 0);
-$x = $C->_new(\"3"); $n = $C->_new(\"0"); # x ** 0 => 1
-ok (${$C->_str($C->_pow($x,$n))}, 1);
-$x = $C->_new(\"1"); $n = $C->_new(\"3"); # 1 ** y => 1
-ok (${$C->_str($C->_pow($x,$n))}, 1);
-$x = $C->_new(\"5"); $n = $C->_new(\"1"); # x ** 1 => x
-ok (${$C->_str($C->_pow($x,$n))}, 5);
+$x = $C->_new("0"); $n = $C->_new("3"); # 0 ** y => 0
+ok ($C->_str($C->_pow($x,$n)), 0);
+$x = $C->_new("3"); $n = $C->_new("0"); # x ** 0 => 1
+ok ($C->_str($C->_pow($x,$n)), 1);
+$x = $C->_new("1"); $n = $C->_new("3"); # 1 ** y => 1
+ok ($C->_str($C->_pow($x,$n)), 1);
+$x = $C->_new("5"); $n = $C->_new("1"); # x ** 1 => x
+ok ($C->_str($C->_pow($x,$n)), 5);
-$x = $C->_new(\"81"); $n = $C->_new(\"3"); # 81 ** 3 == 531441
-ok (${$C->_str($C->_pow($x,$n))},81 ** 3);
+$x = $C->_new("81"); $n = $C->_new("3"); # 81 ** 3 == 531441
+ok ($C->_str($C->_pow($x,$n)),81 ** 3);
-ok (${$C->_str($C->_root($x,$n))},81);
+ok ($C->_str($C->_root($x,$n)),81);
-$x = $C->_new(\"81");
-ok (${$C->_str($C->_pow($x,$n))},81 ** 3);
-ok (${$C->_str($C->_pow($x,$n))},'150094635296999121'); # 531441 ** 3 ==
+$x = $C->_new("81");
+ok ($C->_str($C->_pow($x,$n)),81 ** 3);
+ok ($C->_str($C->_pow($x,$n)),'150094635296999121'); # 531441 ** 3 ==
-ok (${$C->_str($C->_root($x,$n))},'531441');
-ok (${$C->_str($C->_root($x,$n))},'81');
+ok ($C->_str($C->_root($x,$n)),'531441');
+ok ($C->_str($C->_root($x,$n)),'81');
-$x = $C->_new(\"81"); $n = $C->_new(\"14");
-ok (${$C->_str($C->_pow($x,$n))},'523347633027360537213511521');
-ok (${$C->_str($C->_root($x,$n))},'81');
+$x = $C->_new("81"); $n = $C->_new("14");
+ok ($C->_str($C->_pow($x,$n)),'523347633027360537213511521');
+ok ($C->_str($C->_root($x,$n)),'81');
-$x = $C->_new(\"523347633027360537213511520");
-ok (${$C->_str($C->_root($x,$n))},'80');
+$x = $C->_new("523347633027360537213511520");
+ok ($C->_str($C->_root($x,$n)),'80');
-$x = $C->_new(\"523347633027360537213511522");
-ok (${$C->_str($C->_root($x,$n))},'81');
+$x = $C->_new("523347633027360537213511522");
+ok ($C->_str($C->_root($x,$n)),'81');
my $res = [ qw/ 9 31 99 316 999 3162 9999/ ];
# 99 ** 2 = 9801, 999 ** 2 = 998001 etc
for my $i (2 .. 9)
{
- $x = '9' x $i; $x = $C->_new(\$x);
- $n = $C->_new(\"2");
+ $x = '9' x $i; $x = $C->_new($x);
+ $n = $C->_new("2");
my $rc = '9' x ($i-1). '8' . '0' x ($i-1) . '1';
print "# _pow( ", '9' x $i, ", 2) \n" unless
- ok (${$C->_str($C->_pow($x,$n))},$rc);
+ ok ($C->_str($C->_pow($x,$n)),$rc);
if ($i <= 7)
{
- $x = '9' x $i; $x = $C->_new(\$x);
- $n = '9' x $i; $n = $C->_new(\$n);
+ $x = '9' x $i; $x = $C->_new($x);
+ $n = '9' x $i; $n = $C->_new($n);
print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" unless
- ok (${$C->_str($C->_root($x,$n))},'1');
+ ok ($C->_str($C->_root($x,$n)),'1');
- $x = '9' x $i; $x = $C->_new(\$x);
- $n = $C->_new(\"2");
+ $x = '9' x $i; $x = $C->_new($x);
+ $n = $C->_new("2");
print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" unless
- ok (${$C->_str($C->_root($x,$n))}, $res->[$i-2]);
+ ok ($C->_str($C->_root($x,$n)), $res->[$i-2]);
}
}
##############################################################################
# _fac
-$x = $C->_new(\"0"); ok (${$C->_str($C->_fac($x))},'1');
-$x = $C->_new(\"1"); ok (${$C->_str($C->_fac($x))},'1');
-$x = $C->_new(\"2"); ok (${$C->_str($C->_fac($x))},'2');
-$x = $C->_new(\"3"); ok (${$C->_str($C->_fac($x))},'6');
-$x = $C->_new(\"4"); ok (${$C->_str($C->_fac($x))},'24');
-$x = $C->_new(\"5"); ok (${$C->_str($C->_fac($x))},'120');
-$x = $C->_new(\"10"); ok (${$C->_str($C->_fac($x))},'3628800');
-$x = $C->_new(\"11"); ok (${$C->_str($C->_fac($x))},'39916800');
-$x = $C->_new(\"12"); ok (${$C->_str($C->_fac($x))},'479001600');
-$x = $C->_new(\"13"); ok (${$C->_str($C->_fac($x))},'6227020800');
+$x = $C->_new("0"); ok ($C->_str($C->_fac($x)),'1');
+$x = $C->_new("1"); ok ($C->_str($C->_fac($x)),'1');
+$x = $C->_new("2"); ok ($C->_str($C->_fac($x)),'2');
+$x = $C->_new("3"); ok ($C->_str($C->_fac($x)),'6');
+$x = $C->_new("4"); ok ($C->_str($C->_fac($x)),'24');
+$x = $C->_new("5"); ok ($C->_str($C->_fac($x)),'120');
+$x = $C->_new("10"); ok ($C->_str($C->_fac($x)),'3628800');
+$x = $C->_new("11"); ok ($C->_str($C->_fac($x)),'39916800');
+$x = $C->_new("12"); ok ($C->_str($C->_fac($x)),'479001600');
+$x = $C->_new("13"); ok ($C->_str($C->_fac($x)),'6227020800');
# test that _fac modifes $x in place for small arguments
-$x = $C->_new(\"3"); $C->_fac($x); ok (${$C->_str($x)},'6');
-$x = $C->_new(\"13"); $C->_fac($x); ok (${$C->_str($x)},'6227020800');
+$x = $C->_new("3"); $C->_fac($x); ok ($C->_str($x),'6');
+$x = $C->_new("13"); $C->_fac($x); ok ($C->_str($x),'6227020800');
##############################################################################
# _inc and _dec
foreach (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/)
{
- $x = $C->_new(\"$_"); $C->_inc($x);
- print "# \$x = ",${$C->_str($x)},"\n"
- unless ok (${$C->_str($x)},substr($_,0,length($_)-1) . '2');
- $C->_dec($x); ok (${$C->_str($x)},$_);
+ $x = $C->_new("$_"); $C->_inc($x);
+ print "# \$x = ",$C->_str($x),"\n"
+ unless ok ($C->_str($x),substr($_,0,length($_)-1) . '2');
+ $C->_dec($x); ok ($C->_str($x),$_);
}
foreach (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/)
{
- $x = $C->_new(\"$_"); $C->_inc($x);
- print "# \$x = ",${$C->_str($x)},"\n"
- unless ok (${$C->_str($x)},substr($_,0,length($_)-2) . '20');
- $C->_dec($x); ok (${$C->_str($x)},$_);
+ $x = $C->_new("$_"); $C->_inc($x);
+ print "# \$x = ",$C->_str($x),"\n"
+ unless ok ($C->_str($x),substr($_,0,length($_)-2) . '20');
+ $C->_dec($x); ok ($C->_str($x),$_);
}
foreach (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/)
{
- $x = $C->_new(\"$_"); $C->_inc($x);
- print "# \$x = ",${$C->_str($x)},"\n"
- unless ok (${$C->_str($x)}, '1' . '0' x (length($_)));
- $C->_dec($x); ok (${$C->_str($x)},$_);
+ $x = $C->_new("$_"); $C->_inc($x);
+ print "# \$x = ",$C->_str($x),"\n"
+ unless ok ($C->_str($x), '1' . '0' x (length($_)));
+ $C->_dec($x); ok ($C->_str($x),$_);
}
-$x = $C->_new(\"1000"); $C->_inc($x); ok (${$C->_str($x)},'1001');
-$C->_dec($x); ok (${$C->_str($x)},'1000');
+$x = $C->_new("1000"); $C->_inc($x); ok ($C->_str($x),'1001');
+$C->_dec($x); ok ($C->_str($x),'1000');
my $BL;
{
@@ -332,45 +336,45 @@ my $BL;
$x = '1' . '0' x $BL;
$z = '1' . '0' x ($BL-1); $z .= '1';
-$x = $C->_new(\$x); $C->_inc($x); ok (${$C->_str($x)},$z);
+$x = $C->_new($x); $C->_inc($x); ok ($C->_str($x),$z);
$x = '1' . '0' x $BL; $z = '9' x $BL;
-$x = $C->_new(\$x); $C->_dec($x); ok (${$C->_str($x)},$z);
+$x = $C->_new($x); $C->_dec($x); ok ($C->_str($x),$z);
# should not happen:
-# $x = $C->_new(\"-2"); $y = $C->_new(\"4"); ok ($C->_acmp($x,$y),-1);
+# $x = $C->_new("-2"); $y = $C->_new("4"); ok ($C->_acmp($x,$y),-1);
###############################################################################
# _mod
-$x = $C->_new(\"1000"); $y = $C->_new(\"3");
-ok (${$C->_str(scalar $C->_mod($x,$y))},1);
-$x = $C->_new(\"1000"); $y = $C->_new(\"2");
-ok (${$C->_str(scalar $C->_mod($x,$y))},0);
+$x = $C->_new("1000"); $y = $C->_new("3");
+ok ($C->_str(scalar $C->_mod($x,$y)),1);
+$x = $C->_new("1000"); $y = $C->_new("2");
+ok ($C->_str(scalar $C->_mod($x,$y)),0);
# _and, _or, _xor
-$x = $C->_new(\"5"); $y = $C->_new(\"2");
-ok (${$C->_str(scalar $C->_xor($x,$y))},7);
-$x = $C->_new(\"5"); $y = $C->_new(\"2");
-ok (${$C->_str(scalar $C->_or($x,$y))},7);
-$x = $C->_new(\"5"); $y = $C->_new(\"3");
-ok (${$C->_str(scalar $C->_and($x,$y))},1);
+$x = $C->_new("5"); $y = $C->_new("2");
+ok ($C->_str(scalar $C->_xor($x,$y)),7);
+$x = $C->_new("5"); $y = $C->_new("2");
+ok ($C->_str(scalar $C->_or($x,$y)),7);
+$x = $C->_new("5"); $y = $C->_new("3");
+ok ($C->_str(scalar $C->_and($x,$y)),1);
# _from_hex, _from_bin
-ok (${$C->_str(scalar $C->_from_hex(\"0xFf"))},255);
-ok (${$C->_str(scalar $C->_from_bin(\"0b10101011"))},160+11);
+ok ($C->_str( $C->_from_hex("0xFf")),255);
+ok ($C->_str( $C->_from_bin("0b10101011")),160+11);
# _as_hex, _as_bin
-ok (${$C->_str(scalar $C->_from_hex( $C->_as_hex( $C->_new(\"128"))))}, 128);
-ok (${$C->_str(scalar $C->_from_bin( $C->_as_bin( $C->_new(\"128"))))}, 128);
-ok (${$C->_str(scalar $C->_from_hex( $C->_as_hex( $C->_new(\"0"))))}, 0);
-ok (${$C->_str(scalar $C->_from_bin( $C->_as_bin( $C->_new(\"0"))))}, 0);
-ok ( ${$C->_as_hex( $C->_new(\"0"))}, '0x0');
-ok ( ${$C->_as_bin( $C->_new(\"0"))}, '0b0');
-ok ( ${$C->_as_hex( $C->_new(\"12"))}, '0xc');
-ok ( ${$C->_as_bin( $C->_new(\"12"))}, '0b1100');
+ok ($C->_str( $C->_from_hex( $C->_as_hex( $C->_new("128")))), 128);
+ok ($C->_str( $C->_from_bin( $C->_as_bin( $C->_new("128")))), 128);
+ok ($C->_str( $C->_from_hex( $C->_as_hex( $C->_new("0")))), 0);
+ok ($C->_str( $C->_from_bin( $C->_as_bin( $C->_new("0")))), 0);
+ok ($C->_as_hex( $C->_new("0")), '0x0');
+ok ($C->_as_bin( $C->_new("0")), '0b0');
+ok ($C->_as_hex( $C->_new("12")), '0xc');
+ok ($C->_as_bin( $C->_new("12")), '0b1100');
# _check
-$x = $C->_new(\"123456789");
+$x = $C->_new("123456789");
ok ($C->_check($x),0);
ok ($C->_check(123),'123 is not a reference');
diff --git a/lib/Math/BigInt/t/bigintpm.inc b/lib/Math/BigInt/t/bigintpm.inc
index 4e526676b8..cdefea633a 100644
--- a/lib/Math/BigInt/t/bigintpm.inc
+++ b/lib/Math/BigInt/t/bigintpm.inc
@@ -1683,6 +1683,13 @@ abc:1:abc:NaN
111111111111111111111111111111:111111111111111111111111111111:0
12345678901234567890:12345678901234567890:0
&bgcd
+inf:12:NaN
+-inf:12:NaN
+12:inf:NaN
+12:-inf:NaN
+inf:inf:NaN
+inf:-inf:NaN
+-inf:-inf:NaN
abc:abc:NaN
abc:+0:NaN
+0:abc:NaN
@@ -1693,6 +1700,10 @@ abc:+0:NaN
+2:+3:1
+3:+2:1
-3:+2:1
+-3:-2:1
+-144:-60:12
+144:-60:12
+144:60:12
100:625:25
4096:81:1
1034:804:2
@@ -1717,12 +1728,16 @@ abc:0:NaN
+281474976710656:0:0
+281474976710656:1:0
+281474976710656:+281474976710656:281474976710656
+281474976710656:-1:281474976710656
-2:-3:-4
-1:-1:-1
-6:-6:-6
-7:-4:-8
-7:4:0
-4:7:4
+# negative argument is bitwise shorter than positive [perl #26559]
+30:-3:28
+123:-1:123
# equal arguments are treated special, so also do some test with unequal ones
0xFFFF:0xFFFF:0x0xFFFF
0xFFFFFF:0xFFFFFF:0x0xFFFFFF
@@ -1754,6 +1769,11 @@ abc:0:NaN
-6:-6:-6
-7:4:-3
-4:7:-1
++281474976710656:-1:-1
+30:-3:-1
+30:-4:-2
+300:-76:-68
+-76:300:-68
# equal arguments are treated special, so also do some test with unequal ones
0xFFFF:0xFFFF:0x0xFFFF
0xFFFFFF:0xFFFFFF:0x0xFFFFFF
@@ -1802,6 +1822,10 @@ abc:0:NaN
-4:7:-5
4:-7:-3
-4:-7:5
+30:-3:-29
+30:-4:-30
+300:-76:-360
+-76:300:-360
# equal arguments are treated special, so also do some test with unequal ones
0xFFFF:0xFFFF:0
0xFFFFFF:0xFFFFFF:0
@@ -1916,8 +1940,8 @@ abc:12:NaN
0:0:1
0:1:0
0:2:0
-0:-1:NaN
-0:-2:NaN
+0:-1:inf
+0:-2:inf
1:0:1
1:1:1
1:2:1
@@ -1960,6 +1984,14 @@ abc:12:NaN
10:9:1000000000
10:20:100000000000000000000
123456:2:15241383936
+-2:2:4
+-2:3:-8
+-2:4:16
+-2:5:-32
+-3:2:9
+-3:3:-27
+-3:4:81
+-3:5:-243
&length
100:3
10:2
diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t
index 0ffa4a298a..50fca1dbf1 100755
--- a/lib/Math/BigInt/t/bigintpm.t
+++ b/lib/Math/BigInt/t/bigintpm.t
@@ -10,7 +10,7 @@ BEGIN
my $location = $0; $location =~ s/bigintpm.t//;
unshift @INC, $location; # to locate the testing files
chdir 't' if -d 't';
- plan tests => 2770;
+ plan tests => 2832;
}
use Math::BigInt;
diff --git a/lib/Math/BigInt/t/bigints.t b/lib/Math/BigInt/t/bigints.t
index 6b21a75487..de073e21e5 100644
--- a/lib/Math/BigInt/t/bigints.t
+++ b/lib/Math/BigInt/t/bigints.t
@@ -36,24 +36,24 @@ use Math::BigInt::Scalar;
my $C = 'Math::BigInt::Scalar'; # pass classname to sub's
# _new and _str
-my $x = $C->_new(\"123"); my $y = $C->_new(\"321");
-ok (ref($x),'SCALAR'); ok (${$C->_str($x)},123); ok (${$C->_str($y)},321);
+my $x = $C->_new("123"); my $y = $C->_new("321");
+ok (ref($x),'SCALAR'); ok ($C->_str($x),123); ok ($C->_str($y),321);
# _add, _sub, _mul, _div
-ok (${$C->_str($C->_add($x,$y))},444);
-ok (${$C->_str($C->_sub($x,$y))},123);
-ok (${$C->_str($C->_mul($x,$y))},39483);
-ok (${$C->_str($C->_div($x,$y))},123);
+ok ($C->_str($C->_add($x,$y)),444);
+ok ($C->_str($C->_sub($x,$y)),123);
+ok ($C->_str($C->_mul($x,$y)),39483);
+ok ($C->_str($C->_div($x,$y)),123);
-ok (${$C->_str($C->_mul($x,$y))},39483);
-ok (${$C->_str($x)},39483);
-ok (${$C->_str($y)},321);
-my $z = $C->_new(\"2");
-ok (${$C->_str($C->_add($x,$z))},39485);
+ok ($C->_str($C->_mul($x,$y)),39483);
+ok ($C->_str($x),39483);
+ok ($C->_str($y),321);
+my $z = $C->_new("2");
+ok ($C->_str($C->_add($x,$z)),39485);
my ($re,$rr) = $C->_div($x,$y);
-ok (${$C->_str($re)},123); ok (${$C->_str($rr)},2);
+ok ($C->_str($re),123); ok ($C->_str($rr),2);
# is_zero, _is_one, _one, _zero
ok ($C->_is_zero($x),0);
@@ -67,7 +67,7 @@ ok ($C->_is_odd($C->_one()),1); ok ($C->_is_odd($C->_zero()),0);
ok ($C->_is_even($C->_one()),0); ok ($C->_is_even($C->_zero()),1);
# _digit
-$x = $C->_new(\"123456789");
+$x = $C->_new("123456789");
ok ($C->_digit($x,0),9);
ok ($C->_digit($x,1),8);
ok ($C->_digit($x,2),7);
@@ -76,47 +76,44 @@ ok ($C->_digit($x,-2),2);
ok ($C->_digit($x,-3),3);
# _copy
-$x = $C->_new(\"12356");
-ok (${$C->_str($C->_copy($x))},12356);
+$x = $C->_new("12356");
+ok ($C->_str($C->_copy($x)),12356);
# _acmp
-$x = $C->_new(\"123456789");
-$y = $C->_new(\"987654321");
+$x = $C->_new("123456789");
+$y = $C->_new("987654321");
ok ($C->_acmp($x,$y),-1);
ok ($C->_acmp($y,$x),1);
ok ($C->_acmp($x,$x),0);
ok ($C->_acmp($y,$y),0);
# _div
-$x = $C->_new(\"3333"); $y = $C->_new(\"1111");
-ok (${$C->_str( scalar $C->_div($x,$y))},3);
-$x = $C->_new(\"33333"); $y = $C->_new(\"1111"); ($x,$y) = $C->_div($x,$y);
-ok (${$C->_str($x)},30); ok (${$C->_str($y)},3);
-$x = $C->_new(\"123"); $y = $C->_new(\"1111");
-($x,$y) = $C->_div($x,$y); ok (${$C->_str($x)},0); ok (${$C->_str($y)},123);
+$x = $C->_new("3333"); $y = $C->_new("1111");
+ok ($C->_str( scalar $C->_div($x,$y)),3);
+$x = $C->_new("33333"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y);
+ok ($C->_str($x),30); ok ($C->_str($y),3);
+$x = $C->_new("123"); $y = $C->_new("1111");
+($x,$y) = $C->_div($x,$y); ok ($C->_str($x),0); ok ($C->_str($y),123);
# _num
-$x = $C->_new(\"12345"); $x = $C->_num($x); ok (ref($x)||'',''); ok ($x,12345);
+$x = $C->_new("12345"); $x = $C->_num($x); ok (ref($x)||'',''); ok ($x,12345);
# _len
-$x = $C->_new(\"12345"); $x = $C->_len($x); ok (ref($x)||'',''); ok ($x,5);
+$x = $C->_new("12345"); $x = $C->_len($x); ok (ref($x)||'',''); ok ($x,5);
# _and, _or, _xor
-$x = $C->_new(\"3"); $y = $C->_new(\"4"); ok (${$C->_str( $C->_or($x,$y))},7);
-$x = $C->_new(\"1"); $y = $C->_new(\"4"); ok (${$C->_str( $C->_xor($x,$y))},5);
-$x = $C->_new(\"7"); $y = $C->_new(\"3"); ok (${$C->_str( $C->_and($x,$y))},3);
+$x = $C->_new("3"); $y = $C->_new("4"); ok ($C->_str( $C->_or($x,$y)),7);
+$x = $C->_new("1"); $y = $C->_new("4"); ok ($C->_str( $C->_xor($x,$y)),5);
+$x = $C->_new("7"); $y = $C->_new("3"); ok ($C->_str( $C->_and($x,$y)),3);
# _pow
-$x = $C->_new(\"2"); $y = $C->_new(\"4"); ok (${$C->_str( $C->_pow($x,$y))},16);
-$x = $C->_new(\"2"); $y = $C->_new(\"5"); ok (${$C->_str( $C->_pow($x,$y))},32);
-$x = $C->_new(\"3"); $y = $C->_new(\"3"); ok (${$C->_str( $C->_pow($x,$y))},27);
+$x = $C->_new("2"); $y = $C->_new("4"); ok ($C->_str( $C->_pow($x,$y)),16);
+$x = $C->_new("2"); $y = $C->_new("5"); ok ($C->_str( $C->_pow($x,$y)),32);
+$x = $C->_new("3"); $y = $C->_new("3"); ok ($C->_str( $C->_pow($x,$y)),27);
-# should not happen:
-# $x = $C->_new(\"-2"); $y = $C->_new(\"4"); ok ($C->_acmp($x,$y),-1);
-
# _check
-$x = $C->_new(\"123456789");
+$x = $C->_new("123456789");
ok ($C->_check($x),0);
ok ($C->_check(123),'123 is not a reference');
diff --git a/lib/Math/BigInt/t/biglog.t b/lib/Math/BigInt/t/biglog.t
index 9ed9c2a3d7..cba26435d3 100644
--- a/lib/Math/BigInt/t/biglog.t
+++ b/lib/Math/BigInt/t/biglog.t
@@ -37,7 +37,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 50;
+ plan tests => 53;
}
use Math::BigFloat;
@@ -45,7 +45,7 @@ use Math::BigInt;
my $cl = "Math::BigFloat";
-# these tests are now really fast, since they collapse to blog(10), basically
+# These tests are now really fast, since they collapse to blog(10), basically
# Don't attempt to run them with older versions. You are warned.
# $x < 0 => NaN
@@ -99,6 +99,11 @@ ok ($cl->new('10')->bpow('0.6',10), '3.981071706');
# blog should handle bigint input
ok (Math::BigFloat::blog(Math::BigInt->new(100),10), 2);
+# some integer results
+ok ($cl->new(2)->bpow(32)->blog(2), '32'); # 2 ** 32
+ok ($cl->new(3)->bpow(32)->blog(3), '32'); # 3 ** 32
+ok ($cl->new(2)->bpow(65)->blog(2), '65'); # 2 ** 65
+
# test for bug in bsqrt() not taking negative _e into account
test_bpow ('200','0.5',10, '14.14213562');
test_bpow ('20','0.5',10, '4.472135955');
@@ -127,7 +132,7 @@ sub test_bpow
{
my ($x,$y,$scale,$result) = @_;
- print "# Tried: $x->bpow($y,$scale);\n"
+ print "# Tried: $x->bpow($y,$scale);\n"
unless ok ($cl->new($x)->bpow($y,$scale),$result);
}
diff --git a/lib/Math/BigInt/t/calling.t b/lib/Math/BigInt/t/calling.t
index 3b0ff41dd4..71c6b48c97 100644
--- a/lib/Math/BigInt/t/calling.t
+++ b/lib/Math/BigInt/t/calling.t
@@ -30,7 +30,7 @@ BEGIN
unshift @INC, $location;
}
print "# INC = @INC\n";
- my $tests = 161;
+ my $tests = 160;
plan tests => $tests;
if ($] < 5.006)
{
@@ -95,11 +95,12 @@ while (<DATA>)
$class = 'Math::BigInt';
+# XXX TODO this test does not work/fail.
# test whether use Math::BigInt qw/version/ works
-$try = "use $class ($version.'1');";
-$try .= ' $x = $class->new(123); $x = "$x";';
-eval $try;
-ok_undef ( $_ ); # should result in error!
+#$try = "use $class ($version.'1');";
+#$try .= ' $x = $class->new(123); $x = "$x";';
+#eval $try;
+#ok_undef ( $x ); # should result in error!
# test whether fallback to calc works
$try = "use $class ($version,'lib','foo, bar , ');";
@@ -122,14 +123,6 @@ $try = "use $class ($version,'LiB','$class\::Scalar');";
$try .= ' $x = 2**10; $x = "$x";';
$ans = eval $try; ok ( $ans, "1024");
-# test wether calc => undef (array element not existing) works
-# no longer supported
-#$try = "use $class ($version,'LIB');";
-#$try = "require $class; $class\::import($version,'CALC');";
-#$try .= " \$x = $class\->new(2)**10; \$x = ".'"$x";';
-#print "$try\n";
-#$ans = eval $try; ok ( $ans, 1024);
-
# all done
###############################################################################
diff --git a/lib/Math/BigInt/t/config.t b/lib/Math/BigInt/t/config.t
index 5c480536bd..da75344f2a 100644
--- a/lib/Math/BigInt/t/config.t
+++ b/lib/Math/BigInt/t/config.t
@@ -51,7 +51,7 @@ $cfg = $mbf->config();
ok (ref($cfg),'HASH');
ok ($cfg->{lib},'Math::BigInt::Calc');
-ok ($cfg->{with},$mbi);
+ok ($cfg->{with},'Math::BigInt::Calc');
ok ($cfg->{lib_version}, $Math::BigInt::Calc::VERSION);
ok ($cfg->{class},$mbf);
ok ($cfg->{upgrade}||'','');
diff --git a/lib/Math/BigInt/t/mbimbf.inc b/lib/Math/BigInt/t/mbimbf.inc
index 192b1cc4bf..b9c94c4900 100644
--- a/lib/Math/BigInt/t/mbimbf.inc
+++ b/lib/Math/BigInt/t/mbimbf.inc
@@ -264,9 +264,9 @@ foreach my $c ($mbi,$mbf)
ok ($c->bpow(2,16),65536);
ok ($c->bpow(2,$c->new(16)),65536);
-# ok ($c->new(2**15)->brsft(1),2**14);
-# ok ($c->brsft(2**15,1),2**14);
-# ok ($c->brsft(2**15,$c->new(1)),2**14);
+ ok ($c->new(2**15)->brsft(1),2**14);
+ ok ($c->brsft(2**15,1),2**14);
+ ok ($c->brsft(2**15,$c->new(1)),2**14);
ok ($c->new(2**13)->blsft(1),2**14);
ok ($c->blsft(2**13,1),2**14);
@@ -544,6 +544,17 @@ $x = $mbf->new('12340'); $x->bfround(2); ok ($x,'12340');
$x = $mbi->new('1234'); $x->accuracy(3); $x->bfround(-2);
ok_undef ($x->{_a});
+# test that bfround() and bround() work with large numbers
+
+$x = $mbf->new(1)->bdiv(5678,undef,-63);
+ok ($x, '0.000176118351532229658330398027474462839027826699542092286016203');
+
+$x = $mbf->new(1)->bdiv(5678,undef,-90);
+ok ($x, '0.000176118351532229658330398027474462839027826699542092286016202888340965128566396618527651');
+
+$x = $mbf->new(1)->bdiv(5678,80);
+ok ($x, '0.00017611835153222965833039802747446283902782669954209228601620288834096512856639662');
+
###############################################################################
# rounding with already set precision/accuracy
@@ -565,8 +576,9 @@ ok ($x->{_a},2);
# mantissa/exponent format and A/P
$x = $mbf->new('12345.678'); $x->accuracy(4);
ok ($x,'12350'); ok ($x->{_a},4); ok_undef ($x->{_p});
-ok_undef ($x->{_m}->{_a}); ok_undef ($x->{_e}->{_a});
-ok_undef ($x->{_m}->{_p}); ok_undef ($x->{_e}->{_p});
+
+#ok_undef ($x->{_m}->{_a}); ok_undef ($x->{_e}->{_a});
+#ok_undef ($x->{_m}->{_p}); ok_undef ($x->{_e}->{_p});
# check for no A/P in case of fallback
# result
@@ -792,7 +804,7 @@ while (<DATA>)
$try .= "\$x->$f(\$y);";
- # print "trying $try\n";
+ # print "trying $try\n";
$rc = eval $try;
# convert hex/binary targets to decimal
if ($ans =~ /^(0x0x|0b0b)/)
diff --git a/lib/Math/BigInt/t/mbimbf.t b/lib/Math/BigInt/t/mbimbf.t
index 17cd712b0f..fae3c8cf9c 100644
--- a/lib/Math/BigInt/t/mbimbf.t
+++ b/lib/Math/BigInt/t/mbimbf.t
@@ -31,12 +31,12 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 679
+ plan tests => 684
+ 23; # own tests
}
-use Math::BigInt 1.63;
-use Math::BigFloat 1.38;
+use Math::BigInt 1.70;
+use Math::BigFloat 1.43;
use vars qw/$mbi $mbf/;
@@ -95,7 +95,6 @@ foreach my $class (qw/Math::BigInt Math::BigFloat/)
$class->accuracy(undef); # reset for further tests
$class->precision(undef);
}
-
# bug with flog(Math::BigFloat,Math::BigInt)
$x = Math::BigFloat->new(100);
$x = $x->blog(Math::BigInt->new(10));
diff --git a/lib/Math/BigInt/t/req_mbfw.t b/lib/Math/BigInt/t/req_mbfw.t
index b216c797d9..025722d277 100644
--- a/lib/Math/BigInt/t/req_mbfw.t
+++ b/lib/Math/BigInt/t/req_mbfw.t
@@ -34,12 +34,13 @@ BEGIN
# normal require that calls import automatically (we thus have MBI afterwards)
require Math::BigFloat; my $x = Math::BigFloat->new(1); ++$x; ok ($x,2);
-ok (Math::BigFloat->config()->{with}, 'Math::BigInt' );
+ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Calc' );
# now override
Math::BigFloat->import ( with => 'Math::BigInt::Subclass' );
-ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Subclass' );
+# thw with argument is ignored
+ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Calc' );
# all tests done
diff --git a/lib/Math/BigInt/t/sub_mbf.t b/lib/Math/BigInt/t/sub_mbf.t
index 91fda9762a..9a8b9a396c 100755
--- a/lib/Math/BigInt/t/sub_mbf.t
+++ b/lib/Math/BigInt/t/sub_mbf.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 1772
+ plan tests => 1814
+ 6; # + our own tests
}
diff --git a/lib/Math/BigInt/t/sub_mbi.t b/lib/Math/BigInt/t/sub_mbi.t
index 16968d4847..3e831c5fe4 100755
--- a/lib/Math/BigInt/t/sub_mbi.t
+++ b/lib/Math/BigInt/t/sub_mbi.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 2770
+ plan tests => 2832
+ 5; # +5 own tests
}
diff --git a/lib/Math/BigInt/t/sub_mif.t b/lib/Math/BigInt/t/sub_mif.t
index cbaf06a97c..cd0c863075 100644
--- a/lib/Math/BigInt/t/sub_mif.t
+++ b/lib/Math/BigInt/t/sub_mif.t
@@ -28,7 +28,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 679;
+ plan tests => 684;
}
use Math::BigInt::Subclass;
diff --git a/lib/Math/BigInt/t/upgrade.inc b/lib/Math/BigInt/t/upgrade.inc
index 49dbf91823..4799420fd8 100644
--- a/lib/Math/BigInt/t/upgrade.inc
+++ b/lib/Math/BigInt/t/upgrade.inc
@@ -1263,8 +1263,8 @@ abc:12:NaN
0:0:1
0:1:0
0:2:0
-0:-1:NaN
-0:-2:NaN
+0:-1:inf
+0:-2:inf
1:0:1
1:1:1
1:2:1
@@ -1297,6 +1297,14 @@ abc:12:NaN
-1:-2:1
-1:-3:-1
-1:-4:1
+-2:2:4
+-2:3:-8
+-2:4:16
+-2:5:-32
+-3:2:9
+-3:3:-27
+-3:4:81
+-3:5:-243
10:2:100
10:3:1000
10:4:10000
diff --git a/lib/Math/BigInt/t/upgrade.t b/lib/Math/BigInt/t/upgrade.t
index 3fc4067259..a06aec352e 100644
--- a/lib/Math/BigInt/t/upgrade.t
+++ b/lib/Math/BigInt/t/upgrade.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 2082
+ plan tests => 2098
+ 2; # our own tests
}
diff --git a/lib/Math/BigInt/t/use_mbfw.t b/lib/Math/BigInt/t/use_mbfw.t
index d58de047f2..c6a047143e 100644
--- a/lib/Math/BigInt/t/use_mbfw.t
+++ b/lib/Math/BigInt/t/use_mbfw.t
@@ -29,7 +29,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 3;
+ plan tests => 2;
}
@@ -41,12 +41,12 @@ BEGIN
use Math::BigFloat with => 'Math::BigInt::Subclass', lib => 'BareCalc';
-ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Subclass' );
+ok (Math::BigFloat->config()->{with}, 'Math::BigInt::BareCalc' );
-ok ($Math::BigInt::Subclass::lib, 'BareCalc' );
+# ok ($Math::BigInt::Subclass::lib, 'BareCalc' );
# it never arrives here, but that is a design decision in SubClass
-ok (Math::BigInt->config->{lib}, 'Math::BigInt::Calc' );
+ok (Math::BigInt->config->{lib}, 'Math::BigInt::BareCalc' );
# all tests done
diff --git a/lib/Math/BigInt/t/with_sub.t b/lib/Math/BigInt/t/with_sub.t
index a3af404f55..d7391d94ae 100644
--- a/lib/Math/BigInt/t/with_sub.t
+++ b/lib/Math/BigInt/t/with_sub.t
@@ -28,7 +28,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 1772
+ plan tests => 1814
+ 1;
}
@@ -38,6 +38,7 @@ use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
$class = "Math::BigFloat";
$CL = "Math::BigInt::Calc";
-ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Subclass');
+# the with argument is ignored
+ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Calc');
require 'bigfltpm.inc'; # all tests here for sharing