#
# The following hash values are used:
-# value: unsigned int with actual value (as a Math::BigInt::Calc or similiar)
+# value: unsigned int with actual value (as a Math::BigInt::Calc or similar)
# sign : +,-,NaN,+inf,-inf
# _a : accuracy
# _p : precision
# underlying lib might change the reference!
my $class = "Math::BigInt";
-use 5.006;
+use 5.006002;
-$VERSION = '1.90';
+$VERSION = '1.9992';
@ISA = qw(Exporter);
@EXPORT_OK = qw(objectify bgcd blcm);
use strict;
# Inside overload, the first arg is always an object. If the original code had
-# it reversed (like $x = 2 * $y), then the third paramater is true.
+# it reversed (like $x = 2 * $y), then the third parameter is true.
# In some cases (like add, $x = $x + 2 is the same as $x = 2 + $x) this makes
# no difference, but in some cases it does.
# Thus inheritance of overload operators becomes possible and transparent for
# our subclasses without the need to repeat the entire overload section there.
+# We register ops that are not registerable yet, so suppress warnings
+{ no warnings;
use overload
'=' => sub { $_[0]->copy(); },
},
# the original qw() does not work with the TIESCALAR below, why?
-# Order of arguments unsignificant
+# Order of arguments insignificant
'""' => sub { $_[0]->bstr(); },
'0+' => sub { $_[0]->numify(); }
;
+} # no warnings scope
##############################################################################
# global constants, flags and accessory
$_trap_inf = 0; # are infs ok? set w/ config()
my $nan = 'NaN'; # constants for easier life
-my $CALC = 'Math::BigInt::FastCalc'; # module to do the low level math
- # default is FastCalc.pm
+my $CALC = 'Math::BigInt::Calc'; # module to do the low level math
+ # default is Calc.pm
my $IMPORT = 0; # was import() called yet?
# used to make require work
my %WARN; # warn only once for low-level libs
}
##############################################################################
-# string conversation
+# string conversion
sub bsstr
{
# Round $self according to given parameters, or given second argument's
# parameters or global defaults
- # for speed reasons, _find_round_parameters is embeded here:
+ # for speed reasons, _find_round_parameters is embedded here:
my ($self,$a,$p,$r,@args) = @_;
# $a accuracy, if given by caller
{
$self->bfround(int($p),$r) if !defined $self->{_p} || $self->{_p} <= $p;
}
- # bround() or bfround() already callled bnorm() if nec.
+ # bround() or bfround() already called bnorm() if nec.
$self;
}
$x;
}
+sub bsgn {
+ # Signum function.
+
+ my $self = shift;
+
+ return $self if $self->modify('bsgn');
+
+ return $self -> bone("+") if $self -> is_pos();
+ return $self -> bone("-") if $self -> is_neg();
+ return $self; # zero or NaN
+}
+
sub bneg
{
# (BINT or num_str) return BINT
return $x if $x->modify('bneg');
- # for +0 dont negate (to have always normalized +0). Does nothing for 'NaN'
+ # for +0 do not negate (to have always normalized +0). Does nothing for 'NaN'
$x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $CALC->_is_zero($x->{value}));
$x;
}
return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
# have same sign, so compare absolute values. Don't make tests for zero here
- # because it's actually slower than testin in Calc (especially w/ Pari et al)
+ # because it's actually slower than testing in Calc (especially w/ Pari et al)
# post-normalized compare for internal use (honors signs)
if ($x->{sign} eq '+')
}
# $x && $y both < 0
- $CALC->_acmp($y->{value},$x->{value}); # swaped acmp (lib returns 0,1,-1)
+ $CALC->_acmp($y->{value},$x->{value}); # swapped acmp (lib returns 0,1,-1)
}
sub bacmp
# objectify is costly, so avoid it
if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
{
- ($self,$x,$base,@r) = objectify(1,ref($x),@_);
+ ($self,$x,$base,@r) = objectify(2,@_);
}
return $x if $x->modify('blog');
{
# (BINT or num_str, BINT or num_str) return BINT
# does not modify arguments, but returns new object
- # GCD -- Euclids algorithm, variant C (Knuth Vol 3, pg 341 ff)
+ # GCD -- Euclid's algorithm, variant C (Knuth Vol 3, pg 341 ff)
my $y = shift;
$y = $class->new($y) if !ref($y);
# (BINT or num_str, BINT or num_str, BINT or num_str) return BINT
# set up parameters
- my ($self,$x,$y,$z,@r) = (ref($_[0]),@_);
- # objectify is costly, so avoid it
- if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
- {
- ($self,$x,$y,$z,@r) = objectify(3,@_);
- }
+ my ($self,$x,$y,$z,@r) = objectify(3,@_);
return $x if $x->modify('bmuladd');
if (($x->is_nan() || $y->is_nan()) ||
($x->is_zero() && $y->is_zero()));
- # +-inf / +-inf == NaN, reminder also NaN
+ # +-inf / +-inf == NaN, remainder also NaN
if (($x->{sign} =~ /^[+-]inf$/) && ($y->{sign} =~ /^[+-]inf$/))
{
return wantarray ? ($x->bnan(),$self->bnan()) : $x->bnan();
}
else
{
- $rem->{sign} = '+'; # dont leave -0
+ $rem->{sign} = '+'; # do not leave -0
}
$rem->round(@r);
return ($x,$rem);
}
else
{
- $x->{sign} = '+'; # dont leave -0
+ $x->{sign} = '+'; # do not leave -0
}
$x->round(@r);
}
sub bmodinv
{
- # Modular inverse. given a number which is (hopefully) relatively
- # prime to the modulus, calculate its inverse using Euclid's
- # alogrithm. If the number is not relatively prime to the modulus
- # (i.e. their gcd is not one) then NaN is returned.
+ # Return modular multiplicative inverse: z is the modular inverse of x (mod
+ # y) if and only if x*z (mod y) = 1 (mod y). If the modulus y is larger than
+ # one, x and z are relative primes (i.e., their greatest common divisor is
+ # one).
+ #
+ # If no modular multiplicative inverse exists, NaN is returned.
# set up parameters
my ($self,$x,$y,@r) = (undef,@_);
return $x if $x->modify('bmodinv');
- return $x->bnan()
- if ($y->{sign} ne '+' # -, NaN, +inf, -inf
- || $x->is_zero() # or num == 0
- || $x->{sign} !~ /^[+-]$/ # or num NaN, inf, -inf
- );
-
- # put least residue into $x if $x was negative, and thus make it positive
- $x->bmod($y) if $x->{sign} eq '-';
-
- my $sign;
- ($x->{value},$sign) = $CALC->_modinv($x->{value},$y->{value});
- return $x->bnan() if !defined $x->{value}; # in case no GCD found
- return $x if !defined $sign; # already real result
- $x->{sign} = $sign; # flip/flop see below
- $x->bmod($y); # calc real result
- $x;
+ # Return NaN if one or both arguments is +inf, -inf, or nan.
+
+ return $x->bnan() if ($y->{sign} !~ /^[+-]$/ ||
+ $x->{sign} !~ /^[+-]$/);
+
+ # Return NaN if $y is zero; 1 % 0 makes no sense.
+
+ return $x->bnan() if $y->is_zero();
+
+ # Return 0 in the trivial case. $x % 1 or $x % -1 is zero for all finite
+ # integers $x.
+
+ return $x->bzero() if ($y->is_one() ||
+ $y->is_one('-'));
+
+ # Return NaN if $x = 0, or $x modulo $y is zero. The only valid case when
+ # $x = 0 is when $y = 1 or $y = -1, but that was covered above.
+ #
+ # Note that computing $x modulo $y here affects the value we'll feed to
+ # $CALC->_modinv() below when $x and $y have opposite signs. E.g., if $x =
+ # 5 and $y = 7, those two values are fed to _modinv(), but if $x = -5 and
+ # $y = 7, the values fed to _modinv() are $x = 2 (= -5 % 7) and $y = 7.
+ # The value if $x is affected only when $x and $y have opposite signs.
+
+ $x->bmod($y);
+ return $x->bnan() if $x->is_zero();
+
+ # Compute the modular multiplicative inverse of the absolute values. We'll
+ # correct for the signs of $x and $y later. Return NaN if no GCD is found.
+
+ ($x->{value}, $x->{sign}) = $CALC->_modinv($x->{value}, $y->{value});
+ return $x->bnan() if !defined $x->{value};
+
+ # Library inconsistency workaround: _modinv() in Math::BigInt::GMP versions
+ # <= 1.32 return undef rather than a "+" for the sign.
+
+ $x->{sign} = '+' unless defined $x->{sign};
+
+ # When one or both arguments are negative, we have the following
+ # relations. If x and y are positive:
+ #
+ # modinv(-x, -y) = -modinv(x, y)
+ # modinv(-x, y) = y - modinv(x, y) = -modinv(x, y) (mod y)
+ # modinv( x, -y) = modinv(x, y) - y = modinv(x, y) (mod -y)
+
+ # We must swap the sign of the result if the original $x is negative.
+ # However, we must compensate for ignoring the signs when computing the
+ # inverse modulo. The net effect is that we must swap the sign of the
+ # result if $y is negative.
+
+ $x -> bneg() if $y->{sign} eq '-';
+
+ # Compute $x modulo $y again after correcting the sign.
+
+ $x -> bmod($y) if $x->{sign} ne $y->{sign};
+
+ return $x;
}
sub bmodpow
{
- # takes a very large number to a very large exponent in a given very
- # large modulus, quickly, thanks to binary exponentation. Supports
- # negative exponents.
+ # Modular exponentiation. Raises a very large number to a very large exponent
+ # in a given very large modulus quickly, thanks to binary exponentiation.
+ # Supports negative exponents.
my ($self,$num,$exp,$mod,@r) = objectify(3,@_);
return $num if $num->modify('bmodpow');
- # check modulus for valid values
- return $num->bnan() if ($mod->{sign} ne '+' # NaN, - , -inf, +inf
- || $mod->is_zero());
+ # When the exponent 'e' is negative, use the following relation, which is
+ # based on finding the multiplicative inverse 'd' of 'b' modulo 'm':
+ #
+ # b^(-e) (mod m) = d^e (mod m) where b*d = 1 (mod m)
- # check exponent for valid values
- if ($exp->{sign} =~ /\w/)
- {
- # i.e., if it's NaN, +inf, or -inf...
- return $num->bnan();
- }
+ $num->bmodinv($mod) if ($exp->{sign} eq '-');
- $num->bmodinv ($mod) if ($exp->{sign} eq '-');
+ # Check for valid input. All operands must be finite, and the modulus must be
+ # non-zero.
- # check num for valid values (also NaN if there was no inverse but $exp < 0)
- return $num->bnan() if $num->{sign} !~ /^[+-]$/;
+ return $num->bnan() if ($num->{sign} =~ /NaN|inf/ || # NaN, -inf, +inf
+ $exp->{sign} =~ /NaN|inf/ || # NaN, -inf, +inf
+ $mod->{sign} =~ /NaN|inf/ || # NaN, -inf, +inf
+ $mod->is_zero());
+
+ # Compute 'a (mod m)', ignoring the signs on 'a' and 'm'. If the resulting
+ # value is zero, the output is also zero, regardless of the signs on 'a' and
+ # 'm'.
+
+ my $value = $CALC->_modpow($num->{value}, $exp->{value}, $mod->{value});
+ my $sign = '+';
+
+ # If the resulting value is non-zero, we have four special cases, depending
+ # on the signs on 'a' and 'm'.
+
+ unless ($CALC->_is_zero($value)) {
+
+ # There is a negative sign on 'a' (= $num**$exp) only if the number we
+ # are exponentiating ($num) is negative and the exponent ($exp) is odd.
+
+ if ($num->{sign} eq '-' && $exp->is_odd()) {
+
+ # When both the number 'a' and the modulus 'm' have a negative sign,
+ # use this relation:
+ #
+ # -a (mod -m) = -(a (mod m))
+
+ if ($mod->{sign} eq '-') {
+ $sign = '-';
+ }
+
+ # When only the number 'a' has a negative sign, use this relation:
+ #
+ # -a (mod m) = m - (a (mod m))
+
+ else {
+ # Use copy of $mod since _sub() modifies the first argument.
+ my $mod = $CALC->_copy($mod->{value});
+ $value = $CALC->_sub($mod, $value);
+ $sign = '+';
+ }
+
+ } else {
+
+ # When only the modulus 'm' has a negative sign, use this relation:
+ #
+ # a (mod -m) = (a (mod m)) - m
+ # = -(m - (a (mod m)))
+
+ if ($mod->{sign} eq '-') {
+ # Use copy of $mod since _sub() modifies the first argument.
+ my $mod = $CALC->_copy($mod->{value});
+ $value = $CALC->_sub($mod, $value);
+ $sign = '-';
+ }
+
+ # When neither the number 'a' nor the modulus 'm' have a negative
+ # sign, directly return the already computed value.
+ #
+ # (a (mod m))
+
+ }
- # $mod is positive, sign on $exp is ignored, result also positive
- $num->{value} = $CALC->_modpow($num->{value},$exp->{value},$mod->{value});
- $num;
+ }
+
+ $num->{value} = $value;
+ $num->{sign} = $sign;
+
+ return $num;
}
###############################################################################
##############################################################################
# private stuff (internal use only)
-sub objectify
- {
- # check for strings, if yes, return objects instead
-
- # the first argument is number of args objectify() should look at it will
- # return $count+1 elements, the first will be a classname. This is because
- # overloaded '""' calls bstr($object,undef,undef) and this would result in
- # useless objects being created and thrown away. So we cannot simple loop
- # over @_. If the given count is 0, all arguments will be used.
-
- # If the second arg is a ref, use it as class.
- # If not, try to use it as classname, unless undef, then use $class
- # (aka Math::BigInt). The latter shouldn't happen,though.
-
- # caller: gives us:
- # $x->badd(1); => ref x, scalar y
- # Class->badd(1,2); => classname x (scalar), scalar x, scalar y
- # Class->badd( Class->(1),2); => classname x (scalar), ref x, scalar y
- # Math::BigInt::badd(1,2); => scalar x, scalar y
- # In the last case we check number of arguments to turn it silently into
- # $class,1,2. (We can not take '1' as class ;o)
- # badd($class,1) is not supported (it should, eventually, try to add undef)
- # currently it tries 'Math::BigInt' + 1, which will not work.
-
- # some shortcut for the common cases
- # $x->unary_op();
- return (ref($_[1]),$_[1]) if (@_ == 2) && ($_[0]||0 == 1) && ref($_[1]);
-
- my $count = abs(shift || 0);
-
- my (@a,$k,$d); # resulting array, temp, and downgrade
- if (ref $_[0])
- {
- # okay, got object as first
- $a[0] = ref $_[0];
+sub objectify {
+ # Convert strings and "foreign objects" to the objects we want.
+
+ # The first argument, $count, is the number of following arguments that
+ # objectify() looks at and converts to objects. The first is a classname.
+ # If the given count is 0, all arguments will be used.
+
+ # After the count is read, objectify obtains the name of the class to which
+ # the following arguments are converted. If the second argument is a
+ # reference, use the reference type as the class name. Otherwise, if it is
+ # a string that looks like a class name, use that. Otherwise, use $class.
+
+ # Caller: Gives us:
+ #
+ # $x->badd(1); => ref x, scalar y
+ # Class->badd(1,2); => classname x (scalar), scalar x, scalar y
+ # Class->badd(Class->(1),2); => classname x (scalar), ref x, scalar y
+ # Math::BigInt::badd(1,2); => scalar x, scalar y
+
+ # A shortcut for the common case $x->unary_op():
+
+ return (ref($_[1]), $_[1]) if (@_ == 2) && ($_[0]||0 == 1) && ref($_[1]);
+
+ # Check the context.
+
+ unless (wantarray) {
+ require Carp;
+ Carp::croak ("${class}::objectify() needs list context");
}
- else
+
+ # Get the number of arguments to objectify.
+
+ my $count = shift;
+ $count ||= @_;
+
+ # Initialize the output array.
+
+ my @a = @_;
+
+ # If the first argument is a reference, use that reference type as our
+ # class name. Otherwise, if the first argument looks like a class name,
+ # then use that as our class name. Otherwise, use the default class name.
+
{
- # nope, got 1,2 (Class->xxx(1) => Class,1 and not supported)
- $a[0] = $class;
- $a[0] = shift if $_[0] =~ /^[A-Z].*::/; # classname as first?
+ if (ref($a[0])) { # reference?
+ unshift @a, ref($a[0]);
+ last;
+ }
+ if ($a[0] =~ /^[A-Z].*::/) { # string with class name?
+ last;
+ }
+ unshift @a, $class; # default class name
}
- no strict 'refs';
- # disable downgrading, because Math::BigFLoat->foo('1.0','2.0') needs floats
- if (defined ${"$a[0]::downgrade"})
- {
- $d = ${"$a[0]::downgrade"};
- ${"$a[0]::downgrade"} = undef;
+ no strict 'refs';
+
+ # What we upgrade to, if anything.
+
+ my $up = ${"$a[0]::upgrade"};
+
+ # Disable downgrading, because Math::BigFloat -> foo('1.0','2.0') needs
+ # floats.
+
+ my $down;
+ if (defined ${"$a[0]::downgrade"}) {
+ $down = ${"$a[0]::downgrade"};
+ ${"$a[0]::downgrade"} = undef;
}
- my $up = ${"$a[0]::upgrade"};
- # print STDERR "# Now in objectify, my class is today $a[0], count = $count\n";
- if ($count == 0)
- {
- while (@_)
- {
- $k = shift;
- if (!ref($k))
- {
- $k = $a[0]->new($k);
+ for my $i (1 .. $count) {
+ my $ref = ref $a[$i];
+
+ # If it is an object of the right class, all is fine.
+
+ if ($ref eq $a[0]) {
+ next;
}
- elsif (!defined $up && ref($k) ne $a[0])
- {
- # foreign object, try to convert to integer
- $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k);
- }
- push @a,$k;
- }
- }
- else
- {
- while ($count > 0)
- {
- $count--;
- $k = shift;
- if (!ref($k))
- {
- $k = $a[0]->new($k);
+
+ # Don't do anything with undefs.
+
+ unless (defined($a[$i])) {
+ next;
}
- elsif (!defined $up && ref($k) ne $a[0])
- {
- # foreign object, try to convert to integer
- $k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k);
- }
- push @a,$k;
- }
- push @a,@_; # return other params, too
- }
- if (! wantarray)
- {
- require Carp; Carp::croak ("$class objectify needs list context");
+
+ # Perl scalars are fed to the appropriate constructor.
+
+ unless ($ref) {
+ $a[$i] = $a[0] -> new($a[$i]);
+ next;
+ }
+
+ # Upgrading is OK, so skip further tests if the argument is upgraded.
+
+ if (defined $up && $ref eq $up) {
+ next;
+ }
+
+ # If we want a Math::BigInt, see if the object can become one.
+ # Support the old misnomer as_number().
+
+ if ($a[0] eq 'Math::BigInt') {
+ if ($a[$i] -> can('as_int')) {
+ $a[$i] = $a[$i] -> as_int();
+ next;
+ }
+ if ($a[$i] -> can('as_number')) {
+ $a[$i] = $a[$i] -> as_number();
+ next;
+ }
+ }
+
+ # If we want a Math::BigFloat, see if the object can become one.
+
+ if ($a[0] eq 'Math::BigFloat') {
+ if ($a[$i] -> can('as_float')) {
+ $a[$i] = $a[$i] -> as_float();
+ next;
+ }
+ }
+
+ # Last resort.
+
+ $a[$i] = $a[0] -> new($a[$i]);
}
- ${"$a[0]::downgrade"} = $d;
- @a;
- }
+
+ # Reset the downgrading.
+
+ ${"$a[0]::downgrade"} = $down;
+
+ return @a;
+}
sub _register_callback
{
{
$_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
}
- push @c, \'FastCalc', \'Calc' # if all fail, try these
+ push @c, \'Calc' # if all fail, try these
if $warn_or_die < 2; # but not for "only"
$CALC = ''; # signal error
foreach my $l (@c)
# import done
}
-sub from_hex
- {
- # create a bigint from a hexadecimal string
- my ($self, $hs) = @_;
+sub from_hex {
+ # Create a bigint from a hexadecimal string.
- my $rc = __from_hex($hs);
+ my ($self, $str) = @_;
- return $self->bnan() unless defined $rc;
+ if ($str =~ s/
+ ^
+ ( [+-]? )
+ (0?x)?
+ (
+ [0-9a-fA-F]*
+ ( _ [0-9a-fA-F]+ )*
+ )
+ $
+ //x)
+ {
+ # Get a "clean" version of the string, i.e., non-emtpy and with no
+ # underscores or invalid characters.
- $rc;
- }
+ my $sign = $1;
+ my $chrs = $3;
+ $chrs =~ tr/_//d;
+ $chrs = '0' unless CORE::length $chrs;
-sub from_bin
- {
- # create a bigint from a hexadecimal string
- my ($self, $bs) = @_;
+ # Initialize output.
- my $rc = __from_bin($bs);
+ my $x = Math::BigInt->bzero();
- return $self->bnan() unless defined $rc;
+ # The library method requires a prefix.
- $rc;
- }
+ $x->{value} = $CALC->_from_hex('0x' . $chrs);
-sub from_oct
- {
- # create a bigint from a hexadecimal string
- my ($self, $os) = @_;
+ # Place the sign.
- my $x = $self->bzero();
-
- # strip underscores
- $os =~ s/([0-7])_([0-7])/$1$2/g;
- $os =~ s/([0-7])_([0-7])/$1$2/g;
-
- return $x->bnan() if $os !~ /^[\-\+]?0[0-7]+\z/;
+ if ($sign eq '-' && ! $CALC->_is_zero($x->{value})) {
+ $x->{sign} = '-';
+ }
+
+ return $x;
+ }
- my $sign = '+'; $sign = '-' if $os =~ /^-/;
+ # CORE::hex() parses as much as it can, and ignores any trailing garbage.
+ # For backwards compatibility, we return NaN.
- $os =~ s/^[+-]//; # strip sign
- $x->{value} = $CALC->_from_oct($os);
- $x->{sign} = $sign unless $CALC->_is_zero($x->{value}); # no '-0'
- $x;
- }
+ return $self->bnan();
+}
-sub __from_hex
- {
- # internal
- # convert a (ref to) big hex string to BigInt, return undef for error
- my $hs = shift;
+sub from_oct {
+ # Create a bigint from an octal string.
- my $x = Math::BigInt->bzero();
-
- # strip underscores
- $hs =~ s/([0-9a-fA-F])_([0-9a-fA-F])/$1$2/g;
- $hs =~ s/([0-9a-fA-F])_([0-9a-fA-F])/$1$2/g;
-
- return $x->bnan() if $hs !~ /^[\-\+]?0x[0-9A-Fa-f]+$/;
+ my ($self, $str) = @_;
+
+ if ($str =~ s/
+ ^
+ ( [+-]? )
+ (
+ [0-7]*
+ ( _ [0-7]+ )*
+ )
+ $
+ //x)
+ {
+ # Get a "clean" version of the string, i.e., non-emtpy and with no
+ # underscores or invalid characters.
- my $sign = '+'; $sign = '-' if $hs =~ /^-/;
+ my $sign = $1;
+ my $chrs = $2;
+ $chrs =~ tr/_//d;
+ $chrs = '0' unless CORE::length $chrs;
- $hs =~ s/^[+-]//; # strip sign
- $x->{value} = $CALC->_from_hex($hs);
- $x->{sign} = $sign unless $CALC->_is_zero($x->{value}); # no '-0'
- $x;
- }
+ # Initialize output.
-sub __from_bin
- {
- # internal
- # convert a (ref to) big binary string to BigInt, return undef for error
- my $bs = shift;
+ my $x = Math::BigInt->bzero();
- my $x = Math::BigInt->bzero();
+ # The library method requires a prefix.
- # strip underscores
- $bs =~ s/([01])_([01])/$1$2/g;
- $bs =~ s/([01])_([01])/$1$2/g;
- return $x->bnan() if $bs !~ /^[+-]?0b[01]+$/;
+ $x->{value} = $CALC->_from_oct('0' . $chrs);
- my $sign = '+'; $sign = '-' if $bs =~ /^\-/;
- $bs =~ s/^[+-]//; # strip sign
+ # Place the sign.
- $x->{value} = $CALC->_from_bin($bs);
- $x->{sign} = $sign unless $CALC->_is_zero($x->{value}); # no '-0'
- $x;
- }
+ if ($sign eq '-' && ! $CALC->_is_zero($x->{value})) {
+ $x->{sign} = '-';
+ }
+
+ return $x;
+ }
+
+ # CORE::oct() parses as much as it can, and ignores any trailing garbage.
+ # For backwards compatibility, we return NaN.
+
+ return $self->bnan();
+}
+
+sub from_bin {
+ # Create a bigint from a binary string.
+
+ my ($self, $str) = @_;
+
+ if ($str =~ s/
+ ^
+ ( [+-]? )
+ (0?b)?
+ (
+ [01]*
+ ( _ [01]+ )*
+ )
+ $
+ //x)
+ {
+ # Get a "clean" version of the string, i.e., non-emtpy and with no
+ # underscores or invalid characters.
+
+ my $sign = $1;
+ my $chrs = $3;
+ $chrs =~ tr/_//d;
+ $chrs = '0' unless CORE::length $chrs;
+
+ # Initialize output.
+
+ my $x = Math::BigInt->bzero();
+
+ # The library method requires a prefix.
+
+ $x->{value} = $CALC->_from_bin('0b' . $chrs);
+
+ # Place the sign.
+
+ if ($sign eq '-' && ! $CALC->_is_zero($x->{value})) {
+ $x->{sign} = '-';
+ }
+
+ return $x;
+ }
+
+ # For consistency with from_hex() and from_oct(), we return NaN when the
+ # input is invalid.
+
+ return $self->bnan();
+}
sub _split
{
# invalid input.
my $x = shift;
- # strip white space at front, also extranous leading zeros
+ # strip white space at front, also extraneous 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
# 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 Math::BigInt->from_hex($x) if $x =~ /^[+-]?0x/; # hex string
+ return Math::BigInt->from_bin($x) if $x =~ /^[+-]?0b/; # binary string
+
# strip underscores between digits
$x =~ s/([0-9])_([0-9])/$1$2/g;
$x =~ s/([0-9])_([0-9])/$1$2/g; # do twice for 1_2_3
# will warn if Math::BigInt::GMP cannot be found
use Math::BigInt lib => 'GMP';
- # to supress the warning use this:
+ # to suppress the warning use this:
# use Math::BigInt try => 'GMP';
# dies if GMP cannot be loaded:
$x->digit($n); # return the nth digit, counting from right
$x->digit(-$n); # return the nth digit, counting from left
- # The following all modify their first argument. If you want to preserve
- # $x, use $z = $x->copy()->bXXX($y); See under L<CAVEATS> for why this is
- # necessary when mixing $a = $b assignments with non-overloaded math.
+ # The following all modify their first argument. If you want to pre-
+ # serve $x, use $z = $x->copy()->bXXX($y); See under L<CAVEATS> for
+ # why this is necessary when mixing $a = $b assignments with non-over-
+ # loaded math.
$x->bzero(); # set $x to 0
$x->bnan(); # set $x to NaN
$x->bneg(); # negation
$x->babs(); # absolute value
+ $x->bsgn(); # sign function (-1, 0, 1, or NaN)
$x->bnorm(); # normalize (no-op in BigInt)
$x->bnot(); # two's complement (bit wise not)
$x->binc(); # increment $x by 1
$x->bdec(); # decrement $x by 1
-
+
$x->badd($y); # addition (add $y to $x)
$x->bsub($y); # subtraction (subtract $y from $x)
$x->bmul($y); # multiplication (multiply $x by $y)
$x->bmuladd($y,$z); # $x = $x * $y + $z
$x->bmod($y); # modulus (x % y)
- $x->bmodpow($exp,$mod); # modular exponentation (($num**$exp) % $mod))
- $x->bmodinv($mod); # the inverse of $x in the given modulus $mod
-
+ $x->bmodpow($y,$mod); # modular exponentiation (($x ** $y) % $mod)
+ $x->bmodinv($mod); # modular multiplicative inverse
$x->bpow($y); # power of arguments (x ** y)
$x->blsft($y); # left shift in base 2
$x->brsft($y); # right shift in base 2
- # returns (quo,rem) or quo if in scalar context
+ # returns (quo,rem) or quo if in sca-
+ # lar 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
-
+ # returns (quo,rem) or quo if in sca-
+ # lar context
+
$x->band($y); # bitwise and
$x->bior($y); # bitwise inclusive or
$x->bxor($y); # bitwise exclusive or
$x->blog(); # logarithm of $x to base e (Euler's number)
$x->blog($base); # logarithm of $x to base $base (f.i. 2)
$x->bexp(); # calculate e ** $x where e is Euler's number
-
- $x->round($A,$P,$mode); # round to accuracy or precision using mode $mode
+
+ $x->round($A,$P,$mode); # round to accuracy or precision using
+ # mode $mode
$x->bround($n); # accuracy: preserve $n digits
$x->bfround($n); # $n > 0: round $nth digits,
# $n < 0: round to the $nth digit after the
my $lcm = Math::BigInt::blcm(@values);
$x->length(); # return number of digits in number
- ($xl,$f) = $x->length(); # length of number and length of fraction part,
- # latter is always 0 digits long for BigInts
-
- $x->exponent(); # return exponent as BigInt
- $x->mantissa(); # return (signed) mantissa as BigInt
- $x->parts(); # return (mantissa,exponent) as BigInt
- $x->copy(); # make a true copy of $x (unlike $y = $x;)
- $x->as_int(); # return as BigInt (in BigInt: same as copy())
- $x->numify(); # return as scalar (might overflow!)
-
- # conversation to string (do not modify their argument)
- $x->bstr(); # normalized string (e.g. '3')
- $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
+ ($xl,$f) = $x->length(); # length of number and length of fraction
+ # part, latter is always 0 digits long
+ # for BigInts
+
+ $x->exponent(); # return exponent as BigInt
+ $x->mantissa(); # return (signed) mantissa as BigInt
+ $x->parts(); # return (mantissa,exponent) as BigInt
+ $x->copy(); # make a true copy of $x (unlike $y = $x;)
+ $x->as_int(); # return as BigInt (in BigInt: same as copy())
+ $x->numify(); # return as scalar (might overflow!)
+
+ # conversion to string (do not modify their argument)
+ $x->bstr(); # normalized string (e.g. '3')
+ $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)
- $x->precision(); # return P of $x (or global, if P of $x undef)
- $x->precision($n); # set P of $x to $n
- $x->accuracy(); # return A of $x (or global, if A of $x undef)
- $x->accuracy($n); # set A $x to $n
+ $x->precision(); # return P of $x (or global, if P of $x undef)
+ $x->precision($n); # set P of $x to $n
+ $x->accuracy(); # return A of $x (or global, if A of $x undef)
+ $x->accuracy($n); # set A $x to $n
# Global methods
- 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', 'trunc' or 'common'
- Math::BigInt->config(); # return hash containing configuration
+ 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',
+ # 'trunc' or 'common'
+ Math::BigInt->config(); # return hash containing configuration
=head1 DESCRIPTION
Operations with overloaded operators preserve the arguments which is
exactly what you expect.
-=over 2
-
-=item Input
+=head2 Input
Input values to these routines may be any string, that looks like a number
and results in an integer, including hexadecimal and binary numbers.
Scalars holding numbers may also be passed, but note that non-integer numbers
-may already have lost precision due to the conversation to float. Quote
+may already have lost precision due to the conversion to float. Quote
your input if you want BigInt to see all the digits:
$x = Math::BigInt->new(12345678890123456789); # bad
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")'
results in 'NaN'. This might change in the future, so use always the following
explicit forms to get a zero or NaN:
- $zero = Math::BigInt->bzero();
- $nan = Math::BigInt->bnan();
+ $zero = Math::BigInt->bzero();
+ $nan = Math::BigInt->bnan();
C<bnorm()> on a BigInt object is now effectively a no-op, since the numbers
are always stored in normalized form. If passed a string, creates a BigInt
object from the input.
-=item Output
+=head2 Output
Output values are BigInt objects (normalized), except for the methods which
-return a string (see L<SYNOPSIS>).
+return a string (see L</SYNOPSIS>).
Some routines (C<is_odd()>, C<is_even()>, C<is_zero()>, C<is_one()>,
C<is_nan()>, etc.) return true or false, while others (C<bcmp()>, C<bacmp()>)
return either undef (if NaN is involved), <0, 0 or >0 and are suited for sort.
-=back
-
=head1 METHODS
Each of the methods below (except config(), accuracy() and precision())
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.
+L</ACCURACY and PRECISION> for more information.
-=head2 config()
+=over
+
+=item config()
use Data::Dumper;
loaded etc. The following hash keys are currently filled in with the
appropriate information.
- key Description
- Example
+ key Description
+ Example
============================================================
- lib Name of the low-level math library
- Math::BigInt::Calc
- lib_version Version of low-level math library (see 'lib')
- 0.30
- class The class name of config() you just called
- Math::BigInt
- upgrade To which class math operations might be upgraded
- Math::BigFloat
- downgrade To which class math operations might be downgraded
- undef
- precision Global precision
- undef
- accuracy Global accuracy
- undef
- round_mode Global round mode
- even
- version version number of the class you used
- 1.61
- div_scale Fallback accuracy for div
- 40
- trap_nan If true, traps creation of NaN via croak()
- 1
- trap_inf If true, traps creation of +inf/-inf via croak()
- 1
+ lib Name of the low-level math library
+ Math::BigInt::Calc
+ lib_version Version of low-level math library (see 'lib')
+ 0.30
+ class The class name of config() you just called
+ Math::BigInt
+ upgrade To which class math operations might be upgraded
+ Math::BigFloat
+ downgrade To which class math operations might be
+ downgraded undef
+ precision Global precision
+ undef
+ accuracy Global accuracy
+ undef
+ round_mode Global round mode
+ even
+ version version number of the class you used
+ 1.61
+ div_scale Fallback accuracy for div
+ 40
+ trap_nan If true, traps creation of NaN via croak()
+ 1
+ trap_inf If true, traps creation of +inf/-inf via croak()
+ 1
The following values can be set by passing C<config()> a reference to a hash:
upgrade downgrade precision accuracy round_mode div_scale
Example:
-
- $new_cfg = Math::BigInt->config( { trap_inf => 1, precision => 5 } );
-=head2 accuracy()
+ $new_cfg = Math::BigInt->config(
+ { trap_inf => 1, precision => 5 }
+ );
- $x->accuracy(5); # local for $x
- CLASS->accuracy(5); # global for all members of CLASS
- # Note: This also applies to new()!
+=item accuracy()
- $A = $x->accuracy(); # read out accuracy that affects $x
- $A = CLASS->accuracy(); # read out global accuracy
+ $x->accuracy(5); # local for $x
+ CLASS->accuracy(5); # global for all members of CLASS
+ # Note: This also applies to new()!
+
+ $A = $x->accuracy(); # read out accuracy that affects $x
+ $A = CLASS->accuracy(); # read out global accuracy
Set or get the global or local accuracy, aka how many significant digits the
results have. If you set a global accuracy, then this also applies to new()!
Warning! The accuracy I<sticks>, e.g. once you created a number under the
influence of C<< CLASS->accuracy($A) >>, all results from math operations with
-that number will also be rounded.
+that number will also be rounded.
In most cases, you should probably round the results explicitly using one of
-L<round()>, L<bround()> or L<bfround()> or by passing the desired accuracy
+L</round()>, L</bround()> or L</bfround()> or by passing the desired accuracy
to the math operation as additional parameter:
- my $x = Math::BigInt->new(30000);
- my $y = Math::BigInt->new(7);
- print scalar $x->copy()->bdiv($y, 2); # print 4300
- print scalar $x->copy()->bdiv($y)->bround(2); # print 4300
+ my $x = Math::BigInt->new(30000);
+ my $y = Math::BigInt->new(7);
+ print scalar $x->copy()->bdiv($y, 2); # print 4300
+ print scalar $x->copy()->bdiv($y)->bround(2); # print 4300
-Please see the section about L<ACCURACY and PRECISION> for further details.
+Please see the section about L</ACCURACY and PRECISION> for further details.
Value must be greater than zero. Pass an undef value to disable it:
- $x->accuracy(undef);
- Math::BigInt->accuracy(undef);
+ $x->accuracy(undef);
+ Math::BigInt->accuracy(undef);
Returns the current accuracy. For C<< $x->accuracy() >> it will return either
the local accuracy, or if not defined, the global. This means the return value
represents the accuracy that will be in effect for $x:
- $y = Math::BigInt->new(1234567); # unrounded
- print Math::BigInt->accuracy(4),"\n"; # set 4, print 4
- $x = Math::BigInt->new(123456); # $x will be automatically rounded!
- print "$x $y\n"; # '123500 1234567'
- print $x->accuracy(),"\n"; # will be 4
- print $y->accuracy(),"\n"; # also 4, since global is 4
- print Math::BigInt->accuracy(5),"\n"; # set to 5, print 5
- print $x->accuracy(),"\n"; # still 4
- print $y->accuracy(),"\n"; # 5, since global is 5
+ $y = Math::BigInt->new(1234567); # unrounded
+ print Math::BigInt->accuracy(4),"\n"; # set 4, print 4
+ $x = Math::BigInt->new(123456); # $x will be automatic-
+ # ally rounded!
+ print "$x $y\n"; # '123500 1234567'
+ print $x->accuracy(),"\n"; # will be 4
+ print $y->accuracy(),"\n"; # also 4, since global is 4
+ print Math::BigInt->accuracy(5),"\n"; # set to 5, print 5
+ print $x->accuracy(),"\n"; # still 4
+ print $y->accuracy(),"\n"; # 5, since global is 5
Note: Works also for subclasses like Math::BigFloat. Each class has it's 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 precision()
+=item 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
+ $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
- CLASS->precision(5); # Global for all members of CLASS
- # This also applies to new()!
- CLASS->precision(-5); # ditto
+ CLASS->precision(5); # Global for all members of CLASS
+ # This also applies to new()!
+ CLASS->precision(-5); # ditto
- $P = CLASS->precision(); # read out global precision
- $P = $x->precision(); # read out precision that affects $x
+ $P = CLASS->precision(); # read out global precision
+ $P = $x->precision(); # read out precision that affects $x
-Note: You probably want to use L<accuracy()> instead. With L<accuracy> you
-set the number of digits each result should have, with L<precision> you
+Note: You probably want to use L</accuracy()> instead. With L</accuracy()> you
+set the number of digits each result should have, with L</precision()> you
set the place where to round!
C<precision()> sets or gets the global or local precision, aka at which digit
numbers have digits after the dot. In L<Math::BigFloat>, it will round all
results to P digits after the dot.
-Please see the section about L<ACCURACY and PRECISION> for further details.
+Please see the section about L</ACCURACY and PRECISION> for further details.
Pass an undef value to disable it:
- $x->precision(undef);
- Math::BigInt->precision(undef);
+ $x->precision(undef);
+ Math::BigInt->precision(undef);
Returns the current precision. For C<< $x->precision() >> it will return either
the local precision of $x, or if not defined, the global. This means the return
value represents the prevision that will be in effect for $x:
- $y = Math::BigInt->new(1234567); # unrounded
- print Math::BigInt->precision(4),"\n"; # set 4, print 4
- $x = Math::BigInt->new(123456); # will be automatically rounded
- print $x; # print "120000"!
+ $y = Math::BigInt->new(1234567); # unrounded
+ print Math::BigInt->precision(4),"\n"; # set 4, print 4
+ $x = Math::BigInt->new(123456); # will be automatically rounded
+ print $x; # print "120000"!
Note: Works also for subclasses like L<Math::BigFloat>. Each class has its
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()
+=item brsft()
- $x->brsft($y,$n);
+ $x->brsft($y,$n);
Shifts $x right by $y in base $n. Default is base 2, used are usually 10 and
2, but others work, too.
This will print -3, not -2 (as it would if you divide -5 by 2 and truncate the
result).
-=head2 new()
+=item new()
$x = Math::BigInt->new($str,$A,$P,$R);
input is accepted as decimal, hex (with leading '0x') or binary (with leading
'0b').
-See L<Input> for more info on accepted input formats.
+See L</Input> for more info on accepted input formats.
-=head2 from_oct()
+=item from_oct()
$x = Math::BigInt->from_oct("0775"); # input is octal
-=head2 from_hex()
+Interpret the input as an octal string and return the corresponding value. A
+"0" (zero) prefix is optional. A single underscore character may be placed
+right after the prefix, if present, or between any two digits. If the input is
+invalid, a NaN is returned.
+
+=item from_hex()
$x = Math::BigInt->from_hex("0xcafe"); # input is hexadecimal
-=head2 from_bin()
+Interpret input as a hexadecimal string. A "0x" or "x" prefix is optional. A
+single underscore character may be placed right after the prefix, if present,
+or between any two digits. If the input is invalid, a NaN is returned.
- $x = Math::BigInt->from_oct("0x10011"); # input is binary
+=item from_bin()
-=head2 bnan()
+ $x = Math::BigInt->from_bin("0b10011"); # input is binary
+
+Interpret the input as a binary string. A "0b" or "b" prefix is optional. A
+single underscore character may be placed right after the prefix, if present,
+or between any two digits. If the input is invalid, a NaN is returned.
+
+=item bnan()
$x = Math::BigInt->bnan();
$x->bnan();
-=head2 bzero()
+=item bzero()
$x = Math::BigInt->bzero();
$x->bzero();
-=head2 binf()
+=item binf()
$x = Math::BigInt->binf($sign);
$x->binf();
$x->binf('-');
-=head2 bone()
+=item bone()
$x = Math::BigInt->binf($sign);
$x->bone(); # +1
$x->bone('-'); # -1
-=head2 is_one()/is_zero()/is_nan()/is_inf()
+=item is_one()/is_zero()/is_nan()/is_inf()
-
- $x->is_zero(); # true if arg is +0
- $x->is_nan(); # true if arg is NaN
- $x->is_one(); # true if arg is +1
- $x->is_one('-'); # true if arg is -1
- $x->is_inf(); # true if +inf
- $x->is_inf('-'); # true if -inf (sign is default '+')
+ $x->is_zero(); # true if arg is +0
+ $x->is_nan(); # true if arg is NaN
+ $x->is_one(); # true if arg is +1
+ $x->is_one('-'); # true if arg is -1
+ $x->is_inf(); # true if +inf
+ $x->is_inf('-'); # true if -inf (sign is default '+')
These methods all test the BigInt for being one specific value and return
true or false depending on the input. These are faster than doing something
if ($x == 0)
-=head2 is_pos()/is_neg()/is_positive()/is_negative()
-
+=item is_pos()/is_neg()/is_positive()/is_negative()
+
$x->is_pos(); # true if > 0
$x->is_neg(); # true if < 0
introduced in v1.36, while C<is_pos()> and C<is_neg()> were only introduced
in v1.68.
-=head2 is_odd()/is_even()/is_int()
+=item is_odd()/is_even()/is_int()
$x->is_odd(); # true if odd, false for even
$x->is_even(); # true if even, false for odd
In BigInt, all numbers except C<NaN>, C<+inf> and C<-inf> are integers.
-=head2 bcmp()
+=item bcmp()
$x->bcmp($y);
Compares $x with $y and takes the sign into account.
Returns -1, 0, 1 or undef.
-=head2 bacmp()
+=item bacmp()
$x->bacmp($y);
-Compares $x with $y while ignoring their. Returns -1, 0, 1 or undef.
+Compares $x with $y while ignoring their sign. Returns -1, 0, 1 or undef.
-=head2 sign()
+=item sign()
$x->sign();
$x->binf(); # '+inf'
$x->binf('-'); # '-inf'
-=head2 digit()
+=item digit()
- $x->digit($n); # return the nth digit, counting from right
+ $x->digit($n); # return the nth digit, counting from right
If C<$n> is negative, returns the digit counting from left.
-=head2 bneg()
+=item 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()
+=item babs()
$x->babs();
and from '-inf' to '+inf', respectively. Does nothing for NaN or positive
numbers.
-=head2 bnorm()
+=item bsgn()
+
+ $x->bsgn();
+
+Signum function. Set the number to -1, 0, or 1, depending on whether the
+number is negative, zero, or positive, respectively. Does not modify NaNs.
+
+=item bnorm()
$x->bnorm(); # normalize (no-op)
-=head2 bnot()
+=item bnot()
- $x->bnot();
+ $x->bnot();
Two's complement (bitwise not). This is equivalent to
but faster.
-=head2 binc()
+=item binc()
- $x->binc(); # increment x by 1
+ $x->binc(); # increment x by 1
-=head2 bdec()
+=item bdec()
- $x->bdec(); # decrement x by 1
+ $x->bdec(); # decrement x by 1
-=head2 badd()
+=item badd()
- $x->badd($y); # addition (add $y to $x)
+ $x->badd($y); # addition (add $y to $x)
-=head2 bsub()
+=item bsub()
- $x->bsub($y); # subtraction (subtract $y from $x)
+ $x->bsub($y); # subtraction (subtract $y from $x)
-=head2 bmul()
+=item bmul()
- $x->bmul($y); # multiplication (multiply $x by $y)
+ $x->bmul($y); # multiplication (multiply $x by $y)
-=head2 bmuladd()
+=item bmuladd()
$x->bmuladd($y,$z);
This method was added in v1.87 of Math::BigInt (June 2007).
-=head2 bdiv()
+=item bdiv()
+
+ $x->bdiv($y); # divide, set $x to quotient
+ # return (quo,rem) or quo if scalar
+
+=item bmod()
+
+ $x->bmod($y); # modulus (x % y)
- $x->bdiv($y); # divide, set $x to quotient
- # return (quo,rem) or quo if scalar
+=item bmodinv()
-=head2 bmod()
+ $x->bmodinv($mod); # modular multiplicative inverse
- $x->bmod($y); # modulus (x % y)
+Returns the multiplicative inverse of C<$x> modulo C<$mod>. If
-=head2 bmodinv()
+ $y = $x -> copy() -> bmodinv($mod)
- num->bmodinv($mod); # modular inverse
+then C<$y> is the number closest to zero, and with the same sign as C<$mod>,
+satisfying
-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>.
+ ($x * $y) % $mod = 1 % $mod
-=head2 bmodpow()
+If C<$x> and C<$y> are non-zero, they must be relative primes, i.e.,
+C<bgcd($y, $mod)==1>. 'C<NaN>' is returned when no modular multiplicative
+inverse exists.
- $num->bmodpow($exp,$mod); # modular exponentation
+=item bmodpow()
+
+ $num->bmodpow($exp,$mod); # modular exponentiation
# ($num**$exp % $mod)
Returns the value of C<$num> taken to the power C<$exp> in the modulus
-C<$mod> using binary exponentation. C<bmodpow> is far superior to
+C<$mod> using binary exponentiation. C<bmodpow> is far superior to
writing
$num ** $exp % $mod
bmodinv($num, $mod)
-=head2 bpow()
+=item bpow()
- $x->bpow($y); # power of arguments (x ** y)
+ $x->bpow($y); # power of arguments (x ** y)
-=head2 blog()
+=item blog()
- $x->blog($base, $accuracy); # logarithm of x to the base $base
+ $x->blog($base, $accuracy); # logarithm of x to the base $base
If C<$base> is not defined, Euler's number (e) is used:
- print $x->blog(undef, 100); # log(x) to 100 digits
+ print $x->blog(undef, 100); # log(x) to 100 digits
-=head2 bexp()
+=item bexp()
- $x->bexp($accuracy); # calculate e ** X
+ $x->bexp($accuracy); # calculate e ** X
Calculates the expression C<e ** $x> where C<e> is Euler's number.
This method was added in v1.82 of Math::BigInt (April 2007).
-See also L<blog()>.
+See also L</blog()>.
-=head2 bnok()
+=item bnok()
- $x->bnok($y); # x over y (binomial coefficient n over k)
+ $x->bnok($y); # x over y (binomial coefficient n over k)
Calculates the binomial coefficient n over k, also called the "choose"
function. The result is equivalent to:
This method was added in v1.84 of Math::BigInt (April 2007).
-=head2 bpi()
+=item bpi()
print Math::BigInt->bpi(100), "\n"; # 3
This method was added in v1.87 of Math::BigInt (June 2007).
-=head2 bcos()
+=item bcos()
my $x = Math::BigInt->new(1);
print $x->bcos(100), "\n";
This method was added in v1.87 of Math::BigInt (June 2007).
-=head2 bsin()
+=item bsin()
my $x = Math::BigInt->new(1);
print $x->bsin(100), "\n";
This method was added in v1.87 of Math::BigInt (June 2007).
-=head2 batan2()
+=item batan2()
my $x = Math::BigInt->new(1);
my $y = Math::BigInt->new(1);
This method was added in v1.87 of Math::BigInt (June 2007).
-=head2 batan()
+=item batan()
my $x = Math::BigFloat->new(0.5);
print $x->batan(100), "\n";
This method was added in v1.87 of Math::BigInt (June 2007).
-=head2 blsft()
+=item blsft()
$x->blsft($y); # left shift in base 2
$x->blsft($y,$n); # left shift, in base $n (like 10)
-=head2 brsft()
+=item brsft()
$x->brsft($y); # right shift in base 2
$x->brsft($y,$n); # right shift, in base $n (like 10)
-=head2 band()
+=item band()
$x->band($y); # bitwise and
-=head2 bior()
+=item bior()
$x->bior($y); # bitwise inclusive or
-=head2 bxor()
+=item bxor()
$x->bxor($y); # bitwise exclusive or
-=head2 bnot()
+=item bnot()
$x->bnot(); # bitwise not (two's complement)
-=head2 bsqrt()
+=item bsqrt()
$x->bsqrt(); # calculate square-root
-=head2 broot()
+=item broot()
$x->broot($N);
Calculates the N'th root of C<$x>.
-=head2 bfac()
+=item bfac()
- $x->bfac(); # factorial of $x (1*2*3*4*..$x)
+ $x->bfac(); # factorial of $x (1*2*3*4*..$x)
-=head2 round()
+=item 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()
+=item bround()
$x->bround($N); # accuracy: preserve $N digits
-=head2 bfround()
+=item bfround()
$x->bfround($N);
123456.123456 -2 123456.12
123456.123456 -3 123456.123
-=head2 bfloor()
+=item bfloor()
- $x->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()
+=item 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()
+=item bgcd()
- bgcd(@values); # greatest common divisor (no OO style)
+ bgcd(@values); # greatest common divisor (no OO style)
-=head2 blcm()
+=item blcm()
- blcm(@values); # lowest common multiple (no OO style)
+ blcm(@values); # lowest common multiple (no OO style)
-head2 length()
+=item length()
$x->length();
($xl,$fl) = $x->length();
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()
+=item exponent()
$x->exponent();
Return the exponent of $x as BigInt.
-=head2 mantissa()
+=item mantissa()
$x->mantissa();
Return the signed mantissa of $x as BigInt.
-=head2 parts()
+=item parts()
- $x->parts(); # return (mantissa,exponent) as BigInt
+ $x->parts(); # return (mantissa,exponent) as BigInt
-=head2 copy()
+=item copy()
- $x->copy(); # make a true copy of $x (unlike $y = $x;)
+ $x->copy(); # make a true copy of $x (unlike $y = $x;)
-=head2 as_int()/as_number()
+=item as_int()/as_number()
- $x->as_int();
+ $x->as_int();
Returns $x as a BigInt (truncated towards zero). In BigInt this is the same as
-C<copy()>.
+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()
+
+=item bstr()
$x->bstr();
Returns a normalized string representation of C<$x>.
-=head2 bsstr()
+=item bsstr()
- $x->bsstr(); # normalized string in scientific notation
+ $x->bsstr(); # normalized string in scientific notation
-=head2 as_hex()
+=item as_hex()
- $x->as_hex(); # as signed hexadecimal string with prefixed 0x
+ $x->as_hex(); # as signed hexadecimal string with prefixed 0x
-=head2 as_bin()
+=item as_bin()
- $x->as_bin(); # as signed binary string with prefixed 0b
+ $x->as_bin(); # as signed binary string with prefixed 0b
-=head2 as_oct()
+=item as_oct()
- $x->as_oct(); # as signed octal string with prefixed 0
+ $x->as_oct(); # as signed octal string with prefixed 0
-=head2 numify()
+=item 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.
+This loses precision, to avoid this use L<as_int()|/"as_int()/as_number()"> instead.
-=head2 modify()
+=item modify()
$x->modify('bpowd');
This method returns 0 if the object can be modified with the given
-peration, or 1 if not.
+operation, or 1 if not.
This is used for instance by L<Math::BigInt::Constant>.
-=head2 upgrade()/downgrade()
+=item upgrade()/downgrade()
Set/get the class for downgrade/upgrade operations. Thuis is used
for instance by L<bignum>. The defaults are '', thus the following
print $i + $f,"\n"; # print 246
-=head2 div_scale()
+=item div_scale()
Set/get the number of digits for the default precision in divide
operations.
-=head2 round_mode()
+=item round_mode()
Set/get the current round mode.
+=back
+
=head1 ACCURACY and PRECISION
Since version v1.33, Math::BigInt and Math::BigFloat have full support for
integer like 123 (or 120). A precision of 2 means two digits to the left
of the decimal point are zero, so 123 with P = 1 becomes 120. Note that
numbers with zeros before the decimal point may have different precisions,
-because 1200 can have p = 0, 1 or 2 (depending on what the inital value
+because 1200 can have p = 0, 1 or 2 (depending on what the initial value
was). It could also have p < 0, when the digits after the decimal point
are zero.
The string output (of floating point numbers) will be padded with zeros:
-
+
Initial value P A Result String
------------------------------------------------------------
1234.01 -3 1000 1000
of rounding are possible. (Note that random rounding, as in
Math::Round, is not implemented.)
-=over 2
+=over
=item 'trunc'
The handling of A & P in MBI/MBF (the old core code shipped with Perl
versions <= 5.7.2) is like this:
-=over 2
+=over
=item Precision
=item Accuracy (significant digits)
* fround($a) rounds to $a significant digits
- * only fdiv() and fsqrt() take A as (optional) paramater
+ * only fdiv() and fsqrt() take A as (optional) parameter
+ other operations simply create the same number (fneg etc), or more (fmul)
of digits
+ rounding/truncating is only done when explicitly calling one of fround
assumption that 124 has 3 significant digits, while 120/7 will get you
'17', not '17.1' since 120 is thought to have 2 significant digits.
The rounding after the division then uses the remainder and $y to determine
- wether it must round up or down.
+ whether it must round up or down.
? I have no idea which is the right way. That's why I used a slightly more
? simple scheme and tweaked the few failing testcases to match it.
This is how it works now:
-=over 2
+=over
=item Setting/Accessing
- * You can set the A global via C<< Math::BigInt->accuracy() >> or
- C<< Math::BigFloat->accuracy() >> or whatever class you are using.
- * You can also set P globally by using C<< Math::SomeClass->precision() >>
+ * You can set the A global via Math::BigInt->accuracy() or
+ Math::BigFloat->accuracy() or whatever class you are using.
+ * You can also set P globally by using Math::SomeClass->precision()
likewise.
* Globals are classwide, and not inherited by subclasses.
- * to undefine A, use C<< Math::SomeCLass->accuracy(undef); >>
- * to undefine P, use C<< Math::SomeClass->precision(undef); >>
- * Setting C<< Math::SomeClass->accuracy() >> clears automatically
- C<< Math::SomeClass->precision() >>, and vice versa.
+ * to undefine A, use Math::SomeCLass->accuracy(undef);
+ * to undefine P, use Math::SomeClass->precision(undef);
+ * Setting Math::SomeClass->accuracy() clears automatically
+ Math::SomeClass->precision(), and vice versa.
* To be valid, A must be > 0, P can have any value.
* If P is negative, this means round to the P'th place to the right of the
decimal point; positive values mean to the left of the decimal point.
P of 0 means round to integer.
- * to find out the current global A, use C<< Math::SomeClass->accuracy() >>
- * to find out the current global P, use C<< Math::SomeClass->precision() >>
- * use C<< $x->accuracy() >> respective C<< $x->precision() >> for the local
- setting of C<< $x >>.
- * Please note that C<< $x->accuracy() >> respective C<< $x->precision() >>
- return eventually defined global A or P, when C<< $x >>'s A or P is not
+ * to find out the current global A, use Math::SomeClass->accuracy()
+ * to find out the current global P, use Math::SomeClass->precision()
+ * use $x->accuracy() respective $x->precision() for the local
+ setting of $x.
+ * Please note that $x->accuracy() respective $x->precision()
+ return eventually defined global A or P, when $x's A or P is not
set.
=item Creating numbers
globals (if set) will be used. Thus changing the global defaults later on
will not change the A or P of previously created numbers (i.e., A and P of
$x will be what was in effect when $x was created)
- * If given undef for A and P, B<no> rounding will occur, and the globals will
- B<not> be used. This is used by subclasses to create numbers without
+ * If given undef for A and P, NO rounding will occur, and the globals will
+ NOT be used. This is used by subclasses to create numbers without
suffering rounding in the parent. Thus a subclass is able to have its own
globals enforced upon creation of a number by using
- C<< $x = Math::BigInt->new($number,undef,undef) >>:
+ $x = Math::BigInt->new($number,undef,undef):
use Math::BigInt::SomeSubclass;
use Math::BigInt;
Math::BigInt->accuracy(2);
Math::BigInt::SomeSubClass->accuracy(3);
- $x = Math::BigInt::SomeSubClass->new(1234);
+ $x = Math::BigInt::SomeSubClass->new(1234);
$x is now 1230, and not 1200. A subclass might choose to implement
this otherwise, e.g. falling back to the parent's A and P.
and P to -2, globally.
?Maybe an extra option that forbids local A & P settings would be in order,
- ?so that intermediate rounding does not 'poison' further math?
+ ?so that intermediate rounding does not 'poison' further math?
=item Overriding globals
=item Local settings
- * You can set A or P locally by using C<< $x->accuracy() >> or
- C<< $x->precision() >>
+ * You can set A or P locally by using $x->accuracy() or
+ $x->precision()
and thus force different A and P for different objects/numbers.
* Setting A or P this way immediately rounds $x to the new value.
- * C<< $x->accuracy() >> clears C<< $x->precision() >>, and vice versa.
+ * $x->accuracy() clears $x->precision(), and vice versa.
=item Rounding
* the two rounding functions take as the second parameter one of the
following rounding modes (R):
'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
+ * you can set/get the global R by using Math::SomeClass->round_mode()
+ or by setting $Math::SomeClass::round_mode
+ * after each operation, $result->round() is called, and the result may
eventually be rounded (that is, if A or P were set either locally,
globally or as parameter to the operation)
- * to manually round a number, call C<< $x->round($A,$P,$round_mode); >>
+ * to manually round a number, call $x->round($A,$P,$round_mode);
this will round the number by using the appropriate rounding function
and then normalize it.
* rounding modifies the local settings of the number:
While BigInt has extensive handling of inf and NaN, certain quirks remain.
-=over 2
+=over
=item oct()/hex()
=item exp(), cos(), sin(), atan2()
These all might have problems handling infinity right.
-
+
=back
=head1 INTERNALS
-The actual numbers are stored as unsigned big integers (with seperate sign).
+The actual numbers are stored as unsigned big integers (with separate sign).
You should neither care about nor depend on the internal representation; it
might change without notice. Use B<ONLY> method calls like C<< $x->sign(); >>
numbers to decimal (for instance for printing, rounding, calculating their
length in decimal etc).
-So please select carefully what libary you want to use.
+So please select carefully what library you want to use.
Different low-level libraries use different formats to store the numbers.
However, you should B<NOT> depend on the number having a specific format
change.
=head1 EXAMPLES
-
+
use Math::BigInt;
sub bint { Math::BigInt->new(shift); }
=head2 Alternative math libraries
You can use an alternative library to drive Math::BigInt. See the section
-L<MATH LIBRARY> for more information.
+L</MATH LIBRARY> for more information.
For more benchmark results see L<http://bloodgate.com/perl/benchmarks.html>.
-=head2 SUBCLASSING
+=head1 SUBCLASSING
-=head1 Subclassing Math::BigInt
+=head2 Subclassing Math::BigInt
The basic design of Math::BigInt allows simple subclasses with very little
work, as long as a few simple rules are followed:
-=over 2
+=over
=item *
use Math::BigInt upgrade => 'Math::BigFloat';
-As a shortcut, you can use the module C<bignum>:
+As a shortcut, you can use the module L<bignum>:
use bignum;
-Also good for oneliners:
+Also good for one-liners:
perl -Mbignum -le 'print 2 ** 255'
The following methods upgrade themselves unconditionally; that is if upgrade
is in effect, they will always hand up their work:
-=over 2
+=over
=item bsqrt()
Some things might not work as you expect them. Below is documented what is
known to be troublesome:
-=over 1
+=over
=item bstr(), bsstr() and 'cmp'
print "$x eq 9" if $x eq 3*3;
Additionally, the following still works:
-
+
print "$x == 9" if $x == $y;
print "$x == 9" if $x == 9;
print "$x == 9" if $x == 3*3;
$y = Math::BigInt->new($y);
ok ($x,$y); # okay
-Alternatively, simple use C<< <=> >> for comparisons, this will get it
+Alternatively, simply use C<< <=> >> for comparisons, this will get it
always right. There is not yet a way to get a number automatically represented
as a string that matches exactly the way Perl represents it.
$z = $array[$x]; # does work automatically
-=item length
+=item length()
The following will probably not do what you expect:
It prints both the number of digits in the number and in the fraction part
since print calls C<length()> in list context. Use something like:
-
- print scalar $c->length(),"\n"; # prints 3
-=item bdiv
+ print scalar $c->length(),"\n"; # prints 3
+
+=item bdiv()
The following will probably not do what you expect:
It prints both quotient and remainder since print calls C<bdiv()> in list
context. Also, C<bdiv()> will modify $c, so be careful. You probably want
to use
-
+
print $c / 10000,"\n";
- print scalar $c->bdiv(10000),"\n"; # or if you want to modify $c
-instead.
+or, if you want to modify $c instead,
+
+ print scalar $c->bdiv(10000),"\n";
The quotient is always the greatest integer less than or equal to the
real-valued quotient of the two operands, and the remainder (when it is
-nonzero) always has the same sign as the second operand; so, for
+non-zero) always has the same sign as the second operand; so, for
example,
1 / 4 => ( 0, 1)
-inf/-inf = 1, 0 1 * -inf + 0 = -inf
inf/-inf = -1, 0 -1 * -inf + 0 = inf
-inf/ inf = -1, 0 1 * -inf + 0 = -inf
- 8/ 0 = inf, 8 inf * 0 + 8 = 8
- inf/ 0 = inf, inf inf * 0 + inf = inf
+ 8/ 0 = inf, 8 inf * 0 + 8 = 8
+ inf/ 0 = inf, inf inf * 0 + inf = inf
0/ 0 = NaN
These cases below violate the "remainder has the sign of the second of the two
A / B = C, R so that C * B + R = A
========================================================
- -inf/ 0 = -inf, -inf -inf * 0 + inf = -inf
- -8/ 0 = -inf, -8 -inf * 0 + 8 = -8
+ -inf/ 0 = -inf, -inf -inf * 0 + inf = -inf
+ -8/ 0 = -inf, -8 -inf * 0 + 8 = -8
=item Modifying and =
print bpow($x,$i),"\n"; # modify $x
print $x->bpow($i),"\n"; # ditto
print $x **= $i,"\n"; # the same
- print $x ** $i,"\n"; # leave $x alone
+ print $x ** $i,"\n"; # leave $x alone
The form C<$x **= $y> is faster than C<$x = $x ** $y;>, though.
use Math::BigInt;
use Math::BigFloat;
-
+
$mbf = Math::BigFloat->new(5);
$mbi2 = Math::BigInteger->new(5);
$mbi = Math::BigInteger->new(2);
To get a Math::BigFloat you either need to call the operation manually,
make sure the operands are already of the proper type or casted to that type
via Math::BigFloat->new():
-
+
$float = Math::BigFloat->new($mbi2) / $mbi; # = 2.5
Beware of simple "casting" the entire expression, this would only convert
to the desired resulting type.
Scalar values are a bit different, since:
-
+
$float = 2 + $mbf;
$float = $mbf + 2;
=item brsft()
-For negative numbers in base see also L<brsft|brsft>.
+For negative numbers in base see also L<brsft|/brsft()>.
=back
=head1 SEE ALSO
L<Math::BigFloat>, L<Math::BigRat> and L<Math::Big> as well as
-L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
+L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
The pragmas L<bignum>, L<bigint> and L<bigrat> also might be of interest
because they solve the autoupgrading/downgrading issue, at least partly.