summaryrefslogtreecommitdiff
path: root/lib/Math
diff options
context:
space:
mode:
authorTels <nospam-abuse@bloodgate.com>2007-02-02 16:37:36 +0100
committerSteve Peters <steve@fisharerojo.org>2007-02-19 19:15:15 +0000
commit7b29e1e6248cb420eb34bfdef9ce148f7e604a65 (patch)
treedd61f00fa8eb466bf727b82c61638e0950daae80 /lib/Math
parent3e5928301057155786b1e13b4cc0efad5ef9b27f (diff)
downloadperl-7b29e1e6248cb420eb34bfdef9ce148f7e604a65.tar.gz
[PATCH] integrate Math::BigInt 1.79 and Math::BigInt::FastCalc 0.11
Date: Fri, 2 Feb 2007 15:37:36 +0100 Message-Id: <200702021537.38442@bloodgate.com> Subject: Re: [PATCH] integrate Math::BigInt 1.79 and Math::BigInt::FastCalc 0.11 From: Tels <nospam-abuse@bloodgate.com> Date: Tue, 6 Feb 2007 20:18:48 +0100 Message-Id: <200702062019.05487@bloodgate.com> Also, a fix for @INC in lib/Math/BigInt/t/calling.t Additional tests to perform Pod and Pod coverage testing were left out based on removal of similar test files previously. p4raw-id: //depot/perl@30358
Diffstat (limited to 'lib/Math')
-rw-r--r--lib/Math/BigFloat.pm92
-rw-r--r--lib/Math/BigInt.pm346
-rw-r--r--lib/Math/BigInt/Calc.pm63
-rw-r--r--lib/Math/BigInt/t/alias.inc2
-rw-r--r--lib/Math/BigInt/t/bare_mbf.t4
-rw-r--r--lib/Math/BigInt/t/bare_mbi.t2
-rw-r--r--lib/Math/BigInt/t/bigfltpm.inc16
-rwxr-xr-xlib/Math/BigInt/t/bigfltpm.t2
-rw-r--r--lib/Math/BigInt/t/bigintc.t28
-rw-r--r--lib/Math/BigInt/t/bigintpm.inc21
-rwxr-xr-xlib/Math/BigInt/t/bigintpm.t2
-rw-r--r--lib/Math/BigInt/t/calling.t8
-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/upgrade.inc11
-rw-r--r--lib/Math/BigInt/t/upgrade.t2
-rw-r--r--lib/Math/BigInt/t/with_sub.t2
17 files changed, 458 insertions, 147 deletions
diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm
index c926de033f..f15781155f 100644
--- a/lib/Math/BigFloat.pm
+++ b/lib/Math/BigFloat.pm
@@ -12,7 +12,7 @@ package Math::BigFloat;
# _a : accuracy
# _p : precision
-$VERSION = '1.51';
+$VERSION = '1.53';
require 5.005;
require Exporter;
@@ -67,7 +67,7 @@ my $LOG_10_A = length($LOG_10)-1;
my $LOG_2 =
'0.6931471805599453094172321214581765680755001343602552541206800094933936220';
my $LOG_2_A = length($LOG_2)-1;
-my $HALF = '0.5'; # made into an object if necc.
+my $HALF = '0.5'; # made into an object if nec.
##############################################################################
# the old code had $rnd_mode, so we need to support it, too
@@ -80,7 +80,10 @@ BEGIN
{
# when someone set's $rnd_mode, we catch this and check the value to see
# whether it is valid or not.
- $rnd_mode = 'even'; tie $rnd_mode, 'Math::BigFloat';
+ $rnd_mode = 'even'; tie $rnd_mode, 'Math::BigFloat';
+
+ # we need both of them in this package:
+ *as_int = \&as_number;
}
##############################################################################
@@ -92,7 +95,7 @@ BEGIN
fint facmp fcmp fzero fnan finf finc fdec flog ffac fneg
fceil ffloor frsft flsft fone flog froot
/;
- # valid method's that can be hand-ed up (for AUTOLOAD)
+ # valid methods that can be handed up (for AUTOLOAD)
my %hand_ups = map { $_ => 1 }
qw / is_nan is_inf is_negative is_positive is_pos is_neg
accuracy precision div_scale round_mode fabs fnot
@@ -100,8 +103,8 @@ BEGIN
bone binf bnan bzero
/;
- sub method_alias { exists $methods{$_[0]||''}; }
- sub method_hand_up { exists $hand_ups{$_[0]||''}; }
+ sub _method_alias { exists $methods{$_[0]||''}; }
+ sub _method_hand_up { exists $hand_ups{$_[0]||''}; }
}
##############################################################################
@@ -1953,9 +1956,6 @@ sub bpow
return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
return $x if $x->{sign} =~ /^[+-]inf$/;
- # -2 ** -2 => NaN
- return $x->bnan() if $x->{sign} eq '-' && $y->{sign} eq '-';
-
# cache the result of is_zero
my $y_is_zero = $y->is_zero();
return $x->bone() if $y_is_zero;
@@ -1993,7 +1993,7 @@ sub bpow
{
# modify $x in place!
my $z = $x->copy(); $x->bone();
- return $x->bdiv($z,$a,$p,$r); # round in one go (might ignore y's A!)
+ return scalar $x->bdiv($z,$a,$p,$r); # round in one go (might ignore y's A!)
}
$x->round($a,$p,$r,$y);
}
@@ -2206,6 +2206,11 @@ sub brsft
return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
$n = 2 if !defined $n; $n = $self->new($n);
+
+ # negative amount?
+ return $x->blsft($y->copy()->babs(),$n) if $y->{sign} =~ /^-/;
+
+ # the following call to bdiv() will return either quo or (quo,reminder):
$x->bdiv($n->bpow($y),$a,$p,$r,$y);
}
@@ -2225,6 +2230,10 @@ sub blsft
return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
$n = 2 if !defined $n; $n = $self->new($n);
+
+ # negative amount?
+ return $x->brsft($y->copy()->babs(),$n) if $y->{sign} =~ /^-/;
+
$x->bmul($n->bpow($y),$a,$p,$r,$y);
}
@@ -2245,7 +2254,7 @@ sub AUTOLOAD
my $c = $1 || $class;
no strict 'refs';
$c->import() if $IMPORT == 0;
- if (!method_alias($name))
+ if (!_method_alias($name))
{
if (!defined $name)
{
@@ -2253,7 +2262,7 @@ sub AUTOLOAD
require Carp;
Carp::croak ("$c: Can't call a method without name");
}
- if (!method_hand_up($name))
+ if (!_method_hand_up($name))
{
# delayed load of Carp and avoid recursion
require Carp;
@@ -2368,7 +2377,7 @@ sub import
if ((defined $mbilib) && ($MBI eq 'Math::BigInt::Calc'))
{
# MBI already loaded
- Math::BigInt->import('lib',"$lib,$mbilib", 'objectify');
+ Math::BigInt->import('try',"$lib,$mbilib", 'objectify');
}
else
{
@@ -2381,7 +2390,7 @@ sub import
# Perl < 5.6.0 dies with "out of memory!" when eval() and ':constant' is
# used in the same script, or eval inside import(). So we require MBI:
require Math::BigInt;
- Math::BigInt->import( lib => $lib, 'objectify' );
+ Math::BigInt->import( try => $lib, 'objectify' );
}
if ($@)
{
@@ -2481,6 +2490,25 @@ sub as_bin
$z->as_bin();
}
+sub as_oct
+ {
+ # return number as octal digit string (only for integers defined)
+ my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
+
+ return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
+ return '0' if $x->is_zero();
+
+ return $nan if $x->{_es} ne '+'; # how to do 1e-1 in hex!?
+
+ my $z = $MBI->_copy($x->{_m});
+ if (! $MBI->_is_zero($x->{_e})) # > 0
+ {
+ $MBI->_lsft( $z, $x->{_e},10);
+ }
+ $z = Math::BigInt->new( $x->{sign} . $MBI->_num($z));
+ $z->as_oct();
+ }
+
sub as_number
{
# return copy as a bigint representation of this BigFloat number
@@ -2582,9 +2610,9 @@ Math::BigFloat - Arbitrary size floating point math package
$x->bmod($y); # modulus ($x % $y)
$x->bpow($y); # power of arguments ($x ** $y)
- $x->blsft($y); # left shift
- $x->brsft($y); # right shift
- # return (quo,rem) or quo if scalar
+ $x->blsft($y, $n); # left shift by $y places in base $n
+ $x->brsft($y, $n); # right shift by $y places in base $n
+ # returns (quo,rem) or quo if in scalar context
$x->blog(); # logarithm of $x to base e (Euler's number)
$x->blog($base); # logarithm of $x to base $base (f.i. 2)
@@ -2973,7 +3001,7 @@ don't specify it onem but if you specify one, it will try to load them.
Actually, the lib loading order would be "Bar,Baz,Calc", and then
"Foo,Bar,Baz,Calc", but independent of which lib exists, the result is the
same as trying the latter load alone, except for the fact that one of Bar or
-Baz might be loaded needlessly in an intermediate step (and thus hang around
+Baz might be loaded needlessly in an intermidiate step (and thus hang around
and waste memory). If neither Bar nor Baz exist (or don't work/compile), they
will still be tried to be loaded, but this is not as time/memory consuming as
actually loading one of them. Still, this type of usage is not recommended due
@@ -2994,7 +3022,7 @@ You can even load Math::BigInt afterwards:
But this has the same problems like #5, it will first load Calc
(Math::BigFloat needs Math::BigInt and thus loads it) and then later Bar or
Baz, depending on which of them works and is usable/loadable. Since this
-loads Calc unnecc., it is not recommended.
+loads Calc unnec., it is not recommended.
Since it also possible to just require Math::BigFloat, this poses the question
about what libary this will use:
@@ -3041,7 +3069,7 @@ reasoning and details.
=item bdiv
-The following will probably not do what you expect:
+The following will probably not print what you expect:
print $c->bdiv(123.456),"\n";
@@ -3053,6 +3081,23 @@ bdiv() will modify $c, so be careful. You probably want to use
instead.
+=item brsft
+
+The following will probably not print what you expect:
+
+ my $c = Math::BigFloat->new('3.14159');
+ print $c->brsft(3,10),"\n"; # prints 0.00314153.1415
+
+It prints both quotient and remainder, since print calls C<brsft()> in list
+context. Also, C<< $c->brsft() >> will modify $c, so be careful.
+You probably want to use
+
+ print scalar $c->copy()->brsft(3,10),"\n";
+ # or if you really want to modify $c
+ print scalar $c->brsft(3,10),"\n";
+
+instead.
+
=item Modifying and =
Beware of:
@@ -3128,8 +3173,7 @@ L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
The pragmas L<bignum>, L<bigint> and L<bigrat> might also be of interest
because they solve the autoupgrading/downgrading issue, at least partly.
-The package at
-L<http://search.cpan.org/search?mode=module&query=Math%3A%3ABigInt> contains
+The package at L<http://search.cpan.org/~tels/Math-BigInt> contains
more documentation including a full version history, testcases, empty
subclass files and benchmarks.
@@ -3141,7 +3185,7 @@ the same terms as Perl itself.
=head1 AUTHORS
Mark Biggar, overloaded interface by Ilya Zakharevich.
-Completely rewritten by Tels L<http://bloodgate.com> in 2001 - 2004, and still
-at it in 2005.
+Completely rewritten by Tels L<http://bloodgate.com> in 2001 - 2006, and still
+at it in 2007.
=cut
diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm
index 758d7d8b94..ac351dbae5 100644
--- a/lib/Math/BigInt.pm
+++ b/lib/Math/BigInt.pm
@@ -16,9 +16,9 @@ package Math::BigInt;
# underlying lib might change the reference!
my $class = "Math::BigInt";
-require 5.005;
+use 5.005;
-$VERSION = '1.77';
+$VERSION = '1.79';
@ISA = qw(Exporter);
@EXPORT_OK = qw(objectify bgcd blcm);
@@ -148,7 +148,7 @@ use overload
# These vars are public, but their direct usage is not recommended, use the
# accessor methods instead
-$round_mode = 'even'; # one of 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'
+$round_mode = 'even'; # one of 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'
$accuracy = undef;
$precision = undef;
$div_scale = 40;
@@ -201,7 +201,7 @@ sub round_mode
if (defined $_[0])
{
my $m = shift;
- if ($m !~ /^(even|odd|\+inf|\-inf|zero|trunc)$/)
+ if ($m !~ /^(even|odd|\+inf|\-inf|zero|trunc|common)$/)
{
require Carp; Carp::croak ("Unknown round mode '$m'");
}
@@ -882,7 +882,7 @@ sub _find_round_parameters
return ($self->bnan()) if defined $a && defined $p; # error
$r = ${"$c\::round_mode"} unless defined $r;
- if ($r !~ /^(even|odd|\+inf|\-inf|zero|trunc)$/)
+ if ($r !~ /^(even|odd|\+inf|\-inf|zero|trunc|common)$/)
{
require Carp; Carp::croak ("Unknown round mode '$r'");
}
@@ -939,7 +939,7 @@ sub round
return $self->bnan() if defined $a && defined $p;
$r = ${"$c\::round_mode"} unless defined $r;
- if ($r !~ /^(even|odd|\+inf|\-inf|zero|trunc)$/)
+ if ($r !~ /^(even|odd|\+inf|\-inf|zero|trunc|common)$/)
{
require Carp; Carp::croak ("Unknown round mode '$r'");
}
@@ -953,7 +953,7 @@ sub round
{
$self->bfround($p,$r) if !defined $self->{_p} || $self->{_p} <= $p;
}
- # bround() or bfround() already callled bnorm() if necc.
+ # bround() or bfround() already callled bnorm() if nec.
$self;
}
@@ -1160,7 +1160,7 @@ sub bsub
}
$x->badd($y,@r); # badd does not leave internal zeros
$y->{sign} =~ tr/+\-/-+/; # refix $y (does nothing for NaN)
- $x; # already rounded by badd() or no round necc.
+ $x; # already rounded by badd() or no round nec.
}
sub binc
@@ -1722,7 +1722,7 @@ sub bpow
}
return $upgrade->bpow($upgrade->new($x),$y,@r)
- if defined $upgrade && !$y->isa($self);
+ if defined $upgrade && (!$y->isa($self) || $y->{sign} eq '-');
$r[3] = $y; # no push!
@@ -2226,7 +2226,7 @@ sub bceil
sub as_number
{
# An object might be asked to return itself as bigint on certain overloaded
- # operations, this does exactly this, so that sub classes can simple inherit
+ # operations. This does exactly this, so that sub classes can simple inherit
# it or override with their own integer conversion routine.
$_[0]->copy();
}
@@ -2254,6 +2254,17 @@ sub as_bin
return $s . $CALC->_as_bin($x->{value});
}
+sub as_oct
+ {
+ # return as octal string, with prefixed 0
+ my $x = shift; $x = $class->new($x) if !ref($x);
+
+ return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
+
+ my $s = ''; $s = $x->{sign} if $x->{sign} eq '-';
+ return $s . $CALC->_as_oct($x->{value});
+ }
+
##############################################################################
# private stuff (internal use only)
@@ -2372,6 +2383,7 @@ sub import
$IMPORT++; # remember we did import()
my @a; my $l = scalar @_;
+ my $warn_or_die = 0; # 0 - no warn, 1 - warn, 2 - die
for ( my $i = 0; $i < $l ; $i++ )
{
if ($_[$i] eq ':constant')
@@ -2387,10 +2399,13 @@ sub import
$upgrade = $_[$i+1]; # or undef to disable
$i++;
}
- elsif ($_[$i] =~ /^lib$/i)
+ elsif ($_[$i] =~ /^(lib|try|only)\z/)
{
# this causes a different low lib to take care...
$CALC = $_[$i+1] || '';
+ # lib => 1 (warn on fallback), try => 0 (no warn), only => 2 (die on fallback)
+ $warn_or_die = 1 if $_[$i] eq 'lib';
+ $warn_or_die = 2 if $_[$i] eq 'only';
$i++;
}
else
@@ -2413,10 +2428,14 @@ sub import
{
$_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
}
- push @c, 'FastCalc', 'Calc'; # if all fail, try these
+ push @c, \'FastCalc', \'Calc' # if all fail, try these
+ if $warn_or_die < 2; # but not for "only"
$CALC = ''; # signal error
- foreach my $lib (@c)
+ foreach my $l (@c)
{
+ # fallback libraries are "marked" as \'string', extract string if nec.
+ my $lib = $l; $lib = $$l if ref($l);
+
next if ($lib || '') eq '';
$lib = 'Math::BigInt::'.$lib if $lib !~ /^Math::BigInt/i;
$lib =~ s/\.pm$//;
@@ -2448,7 +2467,8 @@ sub import
add mul div sub dec inc
acmp len digit is_one is_zero is_even is_odd
is_two is_ten
- new copy check from_hex from_bin as_hex as_bin zeros
+ zeros new copy check
+ from_hex from_oct from_bin as_hex as_bin as_oct
rsft lsft xor and or
mod sqrt root fac pow modinv modpow log_int gcd
/)
@@ -2468,6 +2488,13 @@ sub import
if ($ok == 0)
{
$CALC = $lib;
+ if ($warn_or_die > 0 && ref($l))
+ {
+ require Carp;
+ my $msg = "Math::BigInt: couldn't load specified math lib(s), fallback to $lib";
+ Carp::carp ($msg) if $warn_or_die == 1;
+ Carp::croak ($msg) if $warn_or_die == 2;
+ }
last; # found a usable one, break
}
else
@@ -2485,7 +2512,14 @@ sub import
if ($CALC eq '')
{
require Carp;
- Carp::croak ("Couldn't load any math lib, not even 'Calc.pm'");
+ if ($warn_or_die == 2)
+ {
+ Carp::croak ("Couldn't load specified math lib(s) and fallback disallowed");
+ }
+ else
+ {
+ Carp::croak ("Couldn't load any math lib(s), not even fallback to Calc.pm");
+ }
}
# notify callbacks
@@ -2506,6 +2540,51 @@ sub import
# import done
}
+sub from_hex
+ {
+ # create a bigint from a hexadecimal string
+ my ($self, $hs) = @_;
+
+ my $rc = $self->__from_hex($hs);
+
+ return $self->bnan() unless defined $rc;
+
+ $rc;
+ }
+
+sub from_bin
+ {
+ # create a bigint from a hexadecimal string
+ my ($self, $bs) = @_;
+
+ my $rc = $self->__from_bin($bs);
+
+ return $self->bnan() unless defined $rc;
+
+ $rc;
+ }
+
+sub from_oct
+ {
+ # create a bigint from a hexadecimal string
+ my ($self, $os) = @_;
+
+ my $x = $self->bzero();
+
+ # strip underscores
+ $os =~ s/([0-9a-fA-F])_([0-9a-fA-F])/$1$2/g;
+ $os =~ s/([0-9a-fA-F])_([0-9a-fA-F])/$1$2/g;
+
+ return $x->bnan() if $os !~ /^[\-\+]?0[0-9]+$/;
+
+ my $sign = '+'; $sign = '-' if $os =~ /^-/;
+
+ $os =~ s/^[+-]//; # strip sign
+ $x->{value} = $CALC->_from_oct($os);
+ $x->{sign} = $sign unless $CALC->_is_zero($x->{value}); # no '-0'
+ $x;
+ }
+
sub __from_hex
{
# internal
@@ -2535,6 +2614,7 @@ sub __from_bin
my $bs = shift;
my $x = Math::BigInt->bzero();
+
# strip underscores
$bs =~ s/([01])_([01])/$1$2/g;
$bs =~ s/([01])_([01])/$1$2/g;
@@ -2558,12 +2638,12 @@ sub _split
my $x = shift;
# strip white space at front, also extranous leading zeros
- $x =~ s/^\s*([-]?)0*([0-9])/$1$2/g; # will not strip ' .2'
- $x =~ s/^\s+//; # but this will
- $x =~ s/\s+$//g; # strip white space at end
+ $x =~ s/^\s*([-]?)0*([0-9])/$1$2/g; # will not strip ' .2'
+ $x =~ s/^\s+//; # but this will
+ $x =~ s/\s+$//g; # strip white space at end
# shortcut, if nothing to split, return early
- if ($x =~ /^[+-]?\d+\z/)
+ if ($x =~ /^[+-]?[0-9]+\z/)
{
$x =~ s/^([+-])0*([0-9])/$2/; my $sign = $1 || '+';
return (\$sign, \$x, \'', \'', \0);
@@ -2572,12 +2652,12 @@ sub _split
# invalid starting char?
return if $x !~ /^[+-]?(\.?[0-9]|0b[0-1]|0x[0-9a-fA-F])/;
- return __from_hex($x) if $x =~ /^[\-\+]?0x/; # hex string
- return __from_bin($x) if $x =~ /^[\-\+]?0b/; # binary string
+ return __from_hex($x) if $x =~ /^[\-\+]?0x/; # hex string
+ return __from_bin($x) if $x =~ /^[\-\+]?0b/; # binary string
# strip underscores between digits
- $x =~ s/(\d)_(\d)/$1$2/g;
- $x =~ s/(\d)_(\d)/$1$2/g; # do twice for 1_2_3
+ $x =~ s/([0-9])_([0-9])/$1$2/g;
+ $x =~ s/([0-9])_([0-9])/$1$2/g; # do twice for 1_2_3
# some possible inputs:
# 2.1234 # 0.12 # 1 # 1E1 # 2.134E1 # 434E-10 # 1.02009E-2
@@ -2590,7 +2670,7 @@ sub _split
# sign,value for exponent,mantint,mantfrac
my ($es,$ev,$mis,$miv,$mfv);
# valid exponent?
- if ($e =~ /^([+-]?)0*(\d+)$/) # strip leading zeros
+ if ($e =~ /^([+-]?)0*([0-9]+)$/) # strip leading zeros
{
$es = $1; $ev = $2;
# valid mantissa?
@@ -2600,10 +2680,10 @@ sub _split
$mi = '0' if !defined $mi;
$mi .= '0' if $mi =~ /^[\-\+]?$/;
$mf = '0' if !defined $mf || $mf eq '';
- if ($mi =~ /^([+-]?)0*(\d+)$/) # strip leading zeros
+ if ($mi =~ /^([+-]?)0*([0-9]+)$/) # strip leading zeros
{
$mis = $1||'+'; $miv = $2;
- return unless ($mf =~ /^(\d*?)0*$/); # strip trailing zeros
+ return unless ($mf =~ /^([0-9]*?)0*$/); # strip trailing zeros
$mfv = $1;
# handle the 0e999 case here
$ev = 0 if $miv eq '0' && $mfv eq '';
@@ -2653,8 +2733,12 @@ Math::BigInt - Arbitrary size integer/float math package
# and always use (it will fall back to pure Perl if the
# GMP library is not installed):
+ # will warn if Math::BigInt::GMP cannot be found
use Math::BigInt lib => 'GMP';
+ # to supress the warning use this:
+ # use Math::BigInt try => 'GMP';
+
my $str = '1234567890';
my @values = (64,74,18);
my $n = 1; my $sign = '-';
@@ -2669,6 +2753,10 @@ Math::BigInt - Arbitrary size integer/float math package
$one = Math::BigInt->bone(); # create a +1
$one = Math::BigInt->bone('-'); # create a -1
+ $h = Math::BigInt->new('0x123'); # from hexadecimal
+ $b = Math::BigInt->new('0b101'); # from binary
+ $o = Math::BigInt->from_oct('0101'); # from octal
+
# Testing (don't modify their arguments)
# (return true if the condition is met, otherwise false)
@@ -2719,10 +2807,12 @@ Math::BigInt - Arbitrary size integer/float math package
$x->bmodinv($mod); # the inverse of $x in the given modulus $mod
$x->bpow($y); # power of arguments (x ** y)
- $x->blsft($y); # left shift
- $x->brsft($y); # right shift
- $x->blsft($y,$n); # left shift, by base $n (like 10)
- $x->brsft($y,$n); # right shift, by base $n (like 10)
+ $x->blsft($y); # left shift in base 10
+ $x->brsft($y); # right shift in base 10
+ # returns (quo,rem) or quo if in scalar context
+ $x->blsft($y,$n); # left shift by $y places in base $n
+ $x->brsft($y,$n); # right shift by $y places in base $n
+ # returns (quo,rem) or quo if in scalar context
$x->band($y); # bitwise and
$x->bior($y); # bitwise inclusive or
@@ -2766,6 +2856,7 @@ Math::BigInt - Arbitrary size integer/float math package
$x->bsstr(); # norm. string in scientific notation (e.g. '3E0')
$x->as_hex(); # as signed hexadecimal string with prefixed 0x
$x->as_bin(); # as signed binary string with prefixed 0b
+ $x->as_oct(); # as signed octal string with prefixed 0
# precision and accuracy (see section about rounding for more)
@@ -2778,7 +2869,7 @@ Math::BigInt - Arbitrary size integer/float math package
Math::BigInt->precision(); # get/set global P for all BigInt objects
Math::BigInt->accuracy(); # get/set global A for all BigInt objects
Math::BigInt->round_mode(); # get/set global round mode, one of
- # 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'
+ # 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'
Math::BigInt->config(); # return hash containing configuration
=head1 DESCRIPTION
@@ -2810,6 +2901,16 @@ You can include one underscore between any two digits.
This means integer values like 1.01E2 or even 1000E-2 are also accepted.
Non-integer values result in NaN.
+Hexadecimal (prefixed with "0x") and binary numbers (prefixed with "0b")
+are accepted, too. Please note that octal numbers are not recognized
+by new(), so the following will print "123":
+
+ perl -MMath::BigInt -le 'print Math::BigInt->new("0123")'
+
+To convert an octal number, use from_oct();
+
+ perl -MMath::BigInt -le 'print Math::BigInt->from_oct("0123")'
+
Currently, Math::BigInt::new() defaults to 0, while Math::BigInt::new('')
results in 'NaN'. This might change in the future, so use always the following
explicit forms to get a zero or NaN:
@@ -2839,7 +2940,7 @@ accepts three additional parameters. These arguments C<$A>, C<$P> and C<$R>
are C<accuracy>, C<precision> and C<round_mode>. Please see the section about
L<ACCURACY and PRECISION> for more information.
-=head2 config
+=head2 config()
use Data::Dumper;
@@ -2887,7 +2988,7 @@ Example:
$new_cfg = Math::BigInt->config( { trap_inf => 1, precision => 5 } );
-=head2 accuracy
+=head2 accuracy()
$x->accuracy(5); # local for $x
CLASS->accuracy(5); # global for all members of CLASS
@@ -2938,7 +3039,7 @@ globals separated from Math::BigInt, but it is possible to subclass
Math::BigInt and make the globals of the subclass aliases to the ones from
Math::BigInt.
-=head2 precision
+=head2 precision()
$x->precision(-2); # local for $x, round at the second digit right of the dot
$x->precision(2); # ditto, round at the second digit left of the dot
@@ -2983,7 +3084,7 @@ own globals separated from Math::BigInt, but it is possible to subclass
Math::BigInt and make the globals of the subclass aliases to the ones from
Math::BigInt.
-=head2 brsft
+=head2 brsft()
$x->brsft($y,$n);
@@ -3008,7 +3109,7 @@ There is one exception, and that is base 2 with negative $x:
This will print -3, not -2 (as it would if you divide -5 by 2 and truncate the
result).
-=head2 new
+=head2 new()
$x = Math::BigInt->new($str,$A,$P,$R);
@@ -3018,7 +3119,19 @@ input is accepted as decimal, hex (with leading '0x') or binary (with leading
See L<Input> for more info on accepted input formats.
-=head2 bnan
+=head2 from_oct()
+
+ $x = Math::BigIn->from_oct("0775"); # input is octal
+
+=head2 from_hex()
+
+ $x = Math::BigIn->from_hex("0xcafe"); # input is hexadecimal
+
+=head2 from_bin()
+
+ $x = Math::BigIn->from_oct("0x10011"); # input is binary
+
+=head2 bnan()
$x = Math::BigInt->bnan();
@@ -3027,7 +3140,7 @@ If used on an object, it will set it to NaN:
$x->bnan();
-=head2 bzero
+=head2 bzero()
$x = Math::BigInt->bzero();
@@ -3036,7 +3149,7 @@ If used on an object, it will set it to zero:
$x->bzero();
-=head2 binf
+=head2 binf()
$x = Math::BigInt->binf($sign);
@@ -3047,7 +3160,7 @@ If used on an object, it will set it to infinity:
$x->binf();
$x->binf('-');
-=head2 bone
+=head2 bone()
$x = Math::BigInt->binf($sign);
@@ -3074,7 +3187,7 @@ like:
if ($x == 0)
-=head2 is_pos()/is_neg()
+=head2 is_pos()/is_neg()/is_positive()/is_negative()
$x->is_pos(); # true if > 0
$x->is_neg(); # true if < 0
@@ -3101,20 +3214,20 @@ C<-inf> are not integers and are neither odd nor even.
In BigInt, all numbers except C<NaN>, C<+inf> and C<-inf> are integers.
-=head2 bcmp
+=head2 bcmp()
$x->bcmp($y);
Compares $x with $y and takes the sign into account.
Returns -1, 0, 1 or undef.
-=head2 bacmp
+=head2 bacmp()
$x->bacmp($y);
Compares $x with $y while ignoring their. Returns -1, 0, 1 or undef.
-=head2 sign
+=head2 sign()
$x->sign();
@@ -3128,20 +3241,20 @@ If you want $x to have a certain sign, use one of the following methods:
$x->binf(); # '+inf'
$x->binf('-'); # '-inf'
-=head2 digit
+=head2 digit()
$x->digit($n); # return the nth digit, counting from right
If C<$n> is negative, returns the digit counting from left.
-=head2 bneg
+=head2 bneg()
$x->bneg();
Negate the number, e.g. change the sign between '+' and '-', or between '+inf'
and '-inf', respectively. Does nothing for NaN or zero.
-=head2 babs
+=head2 babs()
$x->babs();
@@ -3149,11 +3262,11 @@ Set the number to it's absolute value, e.g. change the sign from '-' to '+'
and from '-inf' to '+inf', respectively. Does nothing for NaN or positive
numbers.
-=head2 bnorm
+=head2 bnorm()
$x->bnorm(); # normalize (no-op)
-=head2 bnot
+=head2 bnot()
$x->bnot();
@@ -3163,36 +3276,36 @@ Two's complement (bit wise not). This is equivalent to
but faster.
-=head2 binc
+=head2 binc()
$x->binc(); # increment x by 1
-=head2 bdec
+=head2 bdec()
$x->bdec(); # decrement x by 1
-=head2 badd
+=head2 badd()
$x->badd($y); # addition (add $y to $x)
-=head2 bsub
+=head2 bsub()
$x->bsub($y); # subtraction (subtract $y from $x)
-=head2 bmul
+=head2 bmul()
$x->bmul($y); # multiplication (multiply $x by $y)
-=head2 bdiv
+=head2 bdiv()
$x->bdiv($y); # divide, set $x to quotient
# return (quo,rem) or quo if scalar
-=head2 bmod
+=head2 bmod()
$x->bmod($y); # modulus (x % y)
-=head2 bmodinv
+=head2 bmodinv()
num->bmodinv($mod); # modular inverse
@@ -3200,7 +3313,7 @@ Returns the inverse of C<$num> in the given modulus C<$mod>. 'C<NaN>' is
returned unless C<$num> is relatively prime to C<$mod>, i.e. unless
C<bgcd($num, $mod)==1>.
-=head2 bmodpow
+=head2 bmodpow()
$num->bmodpow($exp,$mod); # modular exponentation
# ($num**$exp % $mod)
@@ -3222,82 +3335,82 @@ is exactly equivalent to
bmodinv($num, $mod)
-=head2 bpow
+=head2 bpow()
$x->bpow($y); # power of arguments (x ** y)
-=head2 blsft
+=head2 blsft()
$x->blsft($y); # left shift
$x->blsft($y,$n); # left shift, in base $n (like 10)
-=head2 brsft
+=head2 brsft()
$x->brsft($y); # right shift
$x->brsft($y,$n); # right shift, in base $n (like 10)
-=head2 band
+=head2 band()
$x->band($y); # bitwise and
-=head2 bior
+=head2 bior()
$x->bior($y); # bitwise inclusive or
-=head2 bxor
+=head2 bxor()
$x->bxor($y); # bitwise exclusive or
-=head2 bnot
+=head2 bnot()
$x->bnot(); # bitwise not (two's complement)
-=head2 bsqrt
+=head2 bsqrt()
$x->bsqrt(); # calculate square-root
-=head2 bfac
+=head2 bfac()
$x->bfac(); # factorial of $x (1*2*3*4*..$x)
-=head2 round
+=head2 round()
$x->round($A,$P,$round_mode);
Round $x to accuracy C<$A> or precision C<$P> using the round mode
C<$round_mode>.
-=head2 bround
+=head2 bround()
$x->bround($N); # accuracy: preserve $N digits
-=head2 bfround
+=head2 bfround()
$x->bfround($N); # round to $Nth digit, no-op for BigInts
-=head2 bfloor
+=head2 bfloor()
$x->bfloor();
Set $x to the integer less or equal than $x. This is a no-op in BigInt, but
does change $x in BigFloat.
-=head2 bceil
+=head2 bceil()
$x->bceil();
Set $x to the integer greater or equal than $x. This is a no-op in BigInt, but
does change $x in BigFloat.
-=head2 bgcd
+=head2 bgcd()
bgcd(@values); # greatest common divisor (no OO style)
-=head2 blcm
+=head2 blcm()
blcm(@values); # lowest common multiplicator (no OO style)
-head2 length
+head2 length()
$x->length();
($xl,$fl) = $x->length();
@@ -3306,27 +3419,27 @@ Returns the number of digits in the decimal representation of the number.
In list context, returns the length of the integer and fraction part. For
BigInt's, the length of the fraction part will always be 0.
-=head2 exponent
+=head2 exponent()
$x->exponent();
Return the exponent of $x as BigInt.
-=head2 mantissa
+=head2 mantissa()
$x->mantissa();
Return the signed mantissa of $x as BigInt.
-=head2 parts
+=head2 parts()
$x->parts(); # return (mantissa,exponent) as BigInt
-=head2 copy
+=head2 copy()
$x->copy(); # make a true copy of $x (unlike $y = $x;)
-=head2 as_int
+=head2 as_int()/as_number()
$x->as_int();
@@ -3336,24 +3449,66 @@ C<copy()>.
C<as_number()> is an alias to this method. C<as_number> was introduced in
v1.22, while C<as_int()> was only introduced in v1.68.
-=head2 bstr
+=head2 bstr()
$x->bstr();
Returns a normalized string representation of C<$x>.
-=head2 bsstr
+=head2 bsstr()
$x->bsstr(); # normalized string in scientific notation
-=head2 as_hex
+=head2 as_hex()
$x->as_hex(); # as signed hexadecimal string with prefixed 0x
-=head2 as_bin
+=head2 as_bin()
$x->as_bin(); # as signed binary string with prefixed 0b
+=head2 as_oct()
+
+ $x->as_oct(); # as signed octal string with prefixed 0
+
+=head2 numify()
+
+ print $x->numify();
+
+This returns a normal Perl scalar from $x. It is used automatically
+whenever a scalar is needed, for instance in array index operations.
+
+This loses precision, to avoid this use L<as_int()> instead.
+
+=head2 modify()
+
+ $x->modify('bpowd');
+
+This method returns 0 if the object can be modified with the given
+peration, or 1 if not.
+
+This is used for instance by L<Math::BigInt::Constant>.
+
+=head2 upgrade()/downgrade()
+
+Set/get the class for downgrade/upgrade operations. Thuis is used
+for instance by L<bignum>. The defaults are '', thus the following
+operation will create a BigInt, not a BigFloat:
+
+ my $i = Math::BigInt->new(123);
+ my $f = Math::BigFloat->new('123.1');
+
+ print $i + $f,"\n"; # print 246
+
+=head2 div_scale()
+
+Set/get the number of digits for the default precision in divide
+operations.
+
+=head2 round_mode()
+
+Set/get the current round mode.
+
=head1 ACCURACY and PRECISION
Since version v1.33, Math::BigInt and Math::BigFloat have full support for
@@ -3480,6 +3635,12 @@ round to zero, i.e. positive numbers down, negative ones up.
E.g., when rounding to the first sigdig, 0.45 becomes 0.4, -0.55
becomes -0.5, but 0.4501 becomes 0.5.
+=item 'common'
+
+round up if the digit immediately to the right of the rounding place
+is 5 or greater, otherwise round down. E.g., 0.15 becomes 0.2 and
+0.149 becomes 0.1.
+
=back
The handling of A & P in MBI/MBF (the old core code shipped with Perl
@@ -3672,7 +3833,7 @@ This is how it works now:
is for precision
* the two rounding functions take as the second parameter one of the
following rounding modes (R):
- 'even', 'odd', '+inf', '-inf', 'zero', 'trunc'
+ 'even', 'odd', '+inf', '-inf', 'zero', 'trunc', 'common'
* you can set/get the global R by using C<< Math::SomeClass->round_mode() >>
or by setting C<< $Math::SomeClass::round_mode >>
* after each operation, C<< $result->round() >> is called, and the result may
@@ -3811,9 +3972,10 @@ that:
C<< ($m,$e) = $x->parts() >> is just a shortcut that gives you both of them
in one go. Both the returned mantissa and exponent have a sign.
-Currently, for BigInts C<$e> is always 0, except for NaN, +inf and -inf,
-where it is C<NaN>; and for C<$x == 0>, where it is C<1> (to be compatible
-with Math::BigFloat's internal representation of a zero as C<0E1>).
+Currently, for BigInts C<$e> is always 0, except +inf and -inf, where it is
+C<+inf>; and for NaN, where it is C<NaN>; and for C<$x == 0>, where it is C<1>
+(to be compatible with Math::BigFloat's internal representation of a zero as
+C<0E1>).
C<$m> is currently just a copy of the original number. The relation between
C<$e> and C<$m> will stay always the same, though their real values might
@@ -3829,7 +3991,7 @@ change.
$x = "$x"; # same as bstr()
$x = Math::BigInt->bneg("1234"); # BigInt "-1234"
$x = Math::BigInt->babs("-12345"); # BigInt "12345"
- $x = Math::BigInt->bnorm("-0 00"); # BigInt "0"
+ $x = Math::BigInt->bnorm("-0.00"); # BigInt "0"
$x = bint(1) + bint(2); # BigInt "3"
$x = bint(1) + "2"; # ditto (auto-BigIntify of "2")
$x = bint(1); # BigInt "1"
@@ -4173,8 +4335,6 @@ effect:
This also works for other subclasses, like Math::String.
-It is yet unclear whether overloaded int() should return a scalar or a BigInt.
-
If you want a real Perl scalar, use C<numify()>:
$y = $x->numify(); # 123 as scalar
@@ -4440,8 +4600,8 @@ subclass files and benchmarks.
=head1 AUTHORS
Original code by Mark Biggar, overloaded interface by Ilya Zakharevich.
-Completely rewritten by Tels http://bloodgate.com in late 2000, 2001 - 2004
-and still at it in 2005.
+Completely rewritten by Tels http://bloodgate.com in late 2000, 2001 - 2006
+and still at it in 2007.
Many people contributed in one or more ways to the final beast, see the file
CREDITS for an (incomplete) list. If you miss your name, please drop me a
diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm
index 856bc0da0f..77ce4de70f 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.47';
+$VERSION = '0.48';
# Package to store unsigned big integers in decimal and do math with them
@@ -272,7 +272,7 @@ sub _add
return $x if (@$y == 1) && $y->[0] == 0; # $x + 0 => $x
if ((@$x == 1) && $x->[0] == 0) # 0 + $y => $y->copy
{
- # twice as slow as $x = [ @$y ], but necc. to retain $x as ref :(
+ # twice as slow as $x = [ @$y ], but nec. to retain $x as ref :(
@$x = @$y; return $x;
}
@@ -1740,7 +1740,7 @@ sub _as_hex
while (@$x1 != 1 || $x1->[0] != 0) # _is_zero()
{
($x1, $xr) = _div($c,$x1,$x10000);
- $es .= unpack($h,pack('v',$xr->[0])); # XXX TODO: why pack('v',...)?
+ $es .= unpack($h,pack('V',$xr->[0]));
}
$es = reverse $es;
$es =~ s/^[0]+//; # strip leading zeros
@@ -1778,14 +1778,62 @@ sub _as_bin
while (!(@$x1 == 1 && $x1->[0] == 0)) # _is_zero()
{
($x1, $xr) = _div($c,$x1,$x10000);
- $es .= unpack($b,pack('v',$xr->[0])); # XXX TODO: why pack('v',...)?
- # $es .= unpack($b,$xr->[0]);
+ $es .= unpack($b,pack('v',$xr->[0]));
}
$es = reverse $es;
$es =~ s/^[0]+//; # strip leading zeros
'0b' . $es; # return result prepended with 0b
}
+sub _as_oct
+ {
+ # convert a decimal number to octal (ref to array, return ref to string)
+ my ($c,$x) = @_;
+
+ # fit's into one element (handle also 0 case)
+ return sprintf("0%o",$x->[0]) if @$x == 1;
+
+ my $x1 = _copy($c,$x);
+
+ my $es = '';
+ my $xr;
+ my $x1000 = [ 0100000 ];
+ while (@$x1 != 1 || $x1->[0] != 0) # _is_zero()
+ {
+ ($x1, $xr) = _div($c,$x1,$x1000);
+ $es .= reverse sprintf("%05o", $xr->[0]);
+ }
+ $es = reverse $es;
+ $es =~ s/^[0]+//; # strip leading zeros
+ '0' . $es; # return result prepended with 0
+ }
+
+sub _from_oct
+ {
+ # convert a octal number to decimal (ref to string, return ref to array)
+ my ($c,$os) = @_;
+
+ # for older Perls, play safe
+ my $m = [ 0100000 ];
+ my $d = 5; # 5 digits at a time
+
+ my $mul = _one();
+ my $x = _zero();
+
+ my $len = int( (length($os)-1)/$d ); # $d digit parts, w/o the '0'
+ my $val; my $i = -$d;
+ while ($len >= 0)
+ {
+ $val = substr($os,$i,$d); # get oct digits
+ $val = oct($val);
+ $i -= $d; $len --;
+ my $adder = [ $val ];
+ _add ($c, $x, _mul ($c, $adder, $mul ) ) if $val != 0;
+ _mul ($c, $mul, $m ) if $len >= 0; # skip last mul
+ }
+ $x;
+ }
+
sub _from_hex
{
# convert a hex number to decimal (ref to string, return ref to array)
@@ -1808,7 +1856,7 @@ sub _from_hex
while ($len >= 0)
{
$val = substr($hs,$i,$d); # get hex digits
- $val =~ s/^[+-]?0x// if $len == 0; # for last part only because
+ $val =~ s/^0x// if $len == 0; # for last part only because
$val = hex($val); # hex does not like wrong chars
$i -= $d; $len --;
my $adder = [ $val ];
@@ -2008,6 +2056,7 @@ Math::BigInt v1.70 or later:
_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
+ _from_oct(str) return ref to new object from ref to octal string
_as_hex(str) return string containing the value as
unsigned hex string, with the '0x' prepended.
@@ -2092,7 +2141,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, speed-up, streamlined and enhanced by Tels 2001 - 2005.
+Fixed, speed-up, streamlined and enhanced by Tels 2001 - 2007.
=head1 SEE ALSO
diff --git a/lib/Math/BigInt/t/alias.inc b/lib/Math/BigInt/t/alias.inc
index b17f317fd2..746a20c99e 100644
--- a/lib/Math/BigInt/t/alias.inc
+++ b/lib/Math/BigInt/t/alias.inc
@@ -6,7 +6,7 @@ my $x = $CL->new(123);
is ($x->is_pos(), 1, '123 is positive');
is ($x->is_neg(), 0, '123 is not negative');
is ($x->as_int(), 123, '123 is 123 as int');
-is (ref($x->as_int()), $CL, "as_int(123) is of class '$CL'");
+is (ref($x->as_int()), 'Math::BigInt', "as_int(123) is of class Math::BigInt");
$x->bneg();
is ($x->is_pos(), 0, '-123 is not positive');
is ($x->is_neg(), 1, '-123 is negative');
diff --git a/lib/Math/BigInt/t/bare_mbf.t b/lib/Math/BigInt/t/bare_mbf.t
index 1cd56c0cb4..3a167e2021 100644
--- a/lib/Math/BigInt/t/bare_mbf.t
+++ b/lib/Math/BigInt/t/bare_mbf.t
@@ -8,7 +8,7 @@ BEGIN
$| = 1;
# to locate the testing files
my $location = $0; $location =~ s/bare_mbf.t//i;
- print "#$0\n";
+ print "# $0\n";
if ($ENV{PERL_CORE})
{
# testing with the core distribution
@@ -27,7 +27,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 2012;
+ plan tests => 2042;
}
use Math::BigFloat lib => 'BareCalc';
diff --git a/lib/Math/BigInt/t/bare_mbi.t b/lib/Math/BigInt/t/bare_mbi.t
index ec6889ba81..13512854ea 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 => 3015;
+ plan tests => 3055;
}
use Math::BigInt lib => 'BareCalc';
diff --git a/lib/Math/BigInt/t/bigfltpm.inc b/lib/Math/BigInt/t/bigfltpm.inc
index 34c4ad61f7..2a45c8278e 100644
--- a/lib/Math/BigInt/t/bigfltpm.inc
+++ b/lib/Math/BigInt/t/bigfltpm.inc
@@ -764,6 +764,22 @@ $round_mode = "even"
-601234500:6:-601234000
+60123456789.0123:5:60123000000
-60123456789.0123:5:-60123000000
+$round_mode = "common"
++60123456789:5:60123000000
+-60123456789:5:-60123000000
++60123456789:6:60123500000
+-60123456789:6:-60123500000
++60123456789:9:60123456800
+-60123456789:9:-60123456800
++601234500:6:601235000
+-601234500:6:-601235000
++601234400:6:601234000
+-601234400:6:-601234000
++601234600:6:601235000
+-601234600:6:-601235000
++601234300:6:601234000
++60123456789.0123:5:60123000000
+-60123456789.0123:5:-60123000000
&ffround
$round_mode = "trunc"
+inf:5:inf
diff --git a/lib/Math/BigInt/t/bigfltpm.t b/lib/Math/BigInt/t/bigfltpm.t
index c44402877b..87c9527ec6 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 => 2012
+ plan tests => 2042
+ 2; # own tests
}
diff --git a/lib/Math/BigInt/t/bigintc.t b/lib/Math/BigInt/t/bigintc.t
index 20d1fb8f86..89b515fcf2 100644
--- a/lib/Math/BigInt/t/bigintc.t
+++ b/lib/Math/BigInt/t/bigintc.t
@@ -8,11 +8,12 @@ BEGIN
$| = 1;
chdir 't' if -d 't';
unshift @INC, '../lib'; # for running manually
- if ($^O eq 'unicos') {
+ if ($^O eq 'unicos') # the tests hang under "unicos"
+ {
print "1..0\n";
exit(0);
- }
- plan tests => 308;
+ }
+ plan tests => 322;
}
use Math::BigInt::Calc;
@@ -363,19 +364,36 @@ 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
+# _from_hex, _from_bin, _from_oct
ok ($C->_str( $C->_from_hex("0xFf")),255);
ok ($C->_str( $C->_from_bin("0b10101011")),160+11);
+ok ($C->_str( $C->_from_oct("0100")), 8*8);
+ok ($C->_str( $C->_from_oct("01000")), 8*8*8);
+ok ($C->_str( $C->_from_oct("010001")), 8*8*8*8+1);
+ok ($C->_str( $C->_from_oct("010007")), 8*8*8*8+7);
-# _as_hex, _as_bin
+# _as_hex, _as_bin, as_oct
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_oct( $C->_as_oct( $C->_new("128")))), 128);
+
+ok ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("123456")))), 123456);
+ok ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("123456789")))), "123456789");
+ok ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new("1234567890123")))), "1234567890123");
+
+my $long = '123456789012345678901234567890';
+ok ($C->_str( $C->_from_hex( $C->_as_hex( $C->_new($long)))), $long);
+ok ($C->_str( $C->_from_bin( $C->_as_bin( $C->_new($long)))), $long);
+ok ($C->_str( $C->_from_oct( $C->_as_oct( $C->_new($long)))), $long);
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->_str( $C->_from_oct( $C->_as_oct( $C->_new("0")))), 0);
ok ($C->_as_hex( $C->_new("0")), '0x0');
ok ($C->_as_bin( $C->_new("0")), '0b0');
+ok ($C->_as_oct( $C->_new("0")), '00');
ok ($C->_as_hex( $C->_new("12")), '0xc');
ok ($C->_as_bin( $C->_new("12")), '0b1100');
+ok ($C->_as_oct( $C->_new("64")), '0100');
# _check
$x = $C->_new("123456789");
diff --git a/lib/Math/BigInt/t/bigintpm.inc b/lib/Math/BigInt/t/bigintpm.inc
index e842a2ac93..07efc283f0 100644
--- a/lib/Math/BigInt/t/bigintpm.inc
+++ b/lib/Math/BigInt/t/bigintpm.inc
@@ -2299,6 +2299,27 @@ $round_mode('even')
+1234567:6:1234570
+12345000:4:12340000
-12345000:4:-12340000
+$round_mode('common')
++60123456789:5:60123000000
++60123199999:5:60123000000
++60123299999:5:60123000000
++60123399999:5:60123000000
++60123499999:5:60123000000
++60123500000:5:60124000000
++60123600000:5:60124000000
++60123700000:5:60124000000
++60123800000:5:60124000000
++60123900000:5:60124000000
+-60123456789:5:-60123000000
+-60123199999:5:-60123000000
+-60123299999:5:-60123000000
+-60123399999:5:-60123000000
+-60123499999:5:-60123000000
+-60123500000:5:-60124000000
+-60123600000:5:-60124000000
+-60123700000:5:-60124000000
+-60123800000:5:-60124000000
+-60123900000:5:-60124000000
&is_zero
0:1
NaNzero:0
diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t
index 7b7dead2b9..5b7302c853 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 => 3015;
+ plan tests => 3055;
}
use Math::BigInt lib => 'Calc';
diff --git a/lib/Math/BigInt/t/calling.t b/lib/Math/BigInt/t/calling.t
index 7376bad0f5..d113d4e8c4 100644
--- a/lib/Math/BigInt/t/calling.t
+++ b/lib/Math/BigInt/t/calling.t
@@ -13,7 +13,7 @@ BEGIN
if ($ENV{PERL_CORE})
{
# testing with the core distribution
- @INC = qw(../lib);
+ @INC = qw(../lib lib);
}
else
{
@@ -55,7 +55,7 @@ use overload;
package main;
-use Math::BigInt lib => 'Calc';
+use Math::BigInt try => 'Calc';
use Math::BigFloat;
my ($x,$y,$z,$u);
@@ -103,7 +103,7 @@ $class = 'Math::BigInt';
#ok_undef ( $x ); # should result in error!
# test whether fallback to calc works
-$try = "use $class ($version,'lib','foo, bar , ');";
+$try = "use $class ($version,'try','foo, bar , ');";
$try .= "$class\->config()->{lib};";
$ans = eval $try;
ok ( $ans =~ /^Math::BigInt::(Fast)?Calc\z/, 1);
@@ -119,7 +119,7 @@ ok ( $ans, "1427247692705959881058285969449495136382746624");
$try = "use $class ($version,'lib','Scalar');";
$try .= ' $x = 2**10; $x = "$x";';
$ans = eval $try; ok ( $ans, "1024");
-$try = "use $class ($version,'LiB','$class\::Scalar');";
+$try = "use $class ($version,'lib','$class\::Scalar');";
$try .= ' $x = 2**10; $x = "$x";';
$ans = eval $try; ok ( $ans, "1024");
diff --git a/lib/Math/BigInt/t/sub_mbf.t b/lib/Math/BigInt/t/sub_mbf.t
index 3033ee2c66..53a3fcb737 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 => 2012
+ plan tests => 2042
+ 6; # + our own tests
}
diff --git a/lib/Math/BigInt/t/sub_mbi.t b/lib/Math/BigInt/t/sub_mbi.t
index af5225499b..4cd9ff4d9c 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 => 3015
+ plan tests => 3055
+ 5; # +5 own tests
}
diff --git a/lib/Math/BigInt/t/upgrade.inc b/lib/Math/BigInt/t/upgrade.inc
index 6545edb6e4..a2ae38cf75 100644
--- a/lib/Math/BigInt/t/upgrade.inc
+++ b/lib/Math/BigInt/t/upgrade.inc
@@ -1277,10 +1277,13 @@ abc:12:NaN
2:2:4
2:3:8
3:3:27
-2:-1:NaN
--2:-1:NaN
-2:-2:NaN
--2:-2:NaN
+2:-1:0.5^
+-2:-1:-0.5^
+2:-2:0.25^
+# Y is even => result positive
+-2:-2:0.25^
+# Y is odd => result negative
+-2:-3:-0.125^
+inf:1234500012:inf
-inf:1234500012:inf
-inf:1234500013:-inf
diff --git a/lib/Math/BigInt/t/upgrade.t b/lib/Math/BigInt/t/upgrade.t
index ac137c1af1..20d8990c55 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 => 2100
+ plan tests => 2112
+ 2; # our own tests
}
diff --git a/lib/Math/BigInt/t/with_sub.t b/lib/Math/BigInt/t/with_sub.t
index 07320a961f..5601a207b6 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 => 2012
+ plan tests => 2042
+ 1;
}