summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/Math/BigInt.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/Math/BigInt.pm')
-rw-r--r--Master/tlpkg/tlperl/lib/Math/BigInt.pm599
1 files changed, 384 insertions, 215 deletions
diff --git a/Master/tlpkg/tlperl/lib/Math/BigInt.pm b/Master/tlpkg/tlperl/lib/Math/BigInt.pm
index f97e4380798..62c021ecf71 100644
--- a/Master/tlpkg/tlperl/lib/Math/BigInt.pm
+++ b/Master/tlpkg/tlperl/lib/Math/BigInt.pm
@@ -6,7 +6,7 @@ package Math::BigInt;
#
# 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
@@ -16,9 +16,9 @@ package Math::BigInt;
# underlying lib might change the reference!
my $class = "Math::BigInt";
-use 5.006;
+use 5.006002;
-$VERSION = '1.89_01';
+$VERSION = '1.994';
@ISA = qw(Exporter);
@EXPORT_OK = qw(objectify bgcd blcm);
@@ -30,7 +30,7 @@ use vars qw/$round_mode $accuracy $precision $div_scale $rnd_mode
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.
@@ -172,8 +172,8 @@ $_trap_nan = 0; # are NaNs ok? set w/ config()
$_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
@@ -799,7 +799,7 @@ sub bone
}
##############################################################################
-# string conversation
+# string conversion
sub bsstr
{
@@ -931,7 +931,7 @@ sub round
# 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
@@ -989,7 +989,7 @@ sub round
{
$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;
}
@@ -1260,7 +1260,7 @@ sub blog
# 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');
@@ -1320,18 +1320,17 @@ sub bnok
}
else
{
- # ( 7 ) 7! 7*6*5 * 4*3*2*1 7 * 6 * 5
- # ( - ) = --------- = --------------- = ---------
- # ( 3 ) 3! (7-3)! 3*2*1 * 4*3*2*1 3 * 2 * 1
+ # ( 7 ) 7! 1*2*3*4 * 5*6*7 5 * 6 * 7 6 7
+ # ( - ) = --------- = --------------- = --------- = 5 * - * -
+ # ( 3 ) (7-3)! 3! 1*2*3*4 * 1*2*3 1 * 2 * 3 2 3
- # compute n - k + 2 (so we start with 5 in the example above)
- my $z = $x - $y;
- if (!$z->is_one())
+ if (!$y->is_zero())
{
+ my $z = $x - $y;
$z->binc();
my $r = $z->copy(); $z->binc();
my $d = $self->new(2);
- while ($z->bacmp($x) <= 0) # f < x ?
+ while ($z->bacmp($x) <= 0) # f <= x ?
{
$r->bmul($z); $r->bdiv($d);
$z->binc(); $d->binc();
@@ -1375,11 +1374,11 @@ sub bexp
else { $x = $u; }
}
-sub blcm
- {
+sub blcm
+ {
# (BINT or num_str, BINT or num_str) return BINT
# does not modify arguments, but returns new object
- # Lowest Common Multiplicator
+ # Lowest Common Multiple
my $y = shift; my ($x);
if (ref($y))
@@ -1403,7 +1402,7 @@ sub bgcd
{
# (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);
@@ -1498,13 +1497,13 @@ sub is_even
sub is_positive
{
- # return true when arg (BINT or num_str) is positive (>= 0)
+ # return true when arg (BINT or num_str) is positive (> 0)
my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
return 1 if $x->{sign} eq '+inf'; # +inf is positive
-
+
# 0+ is neither positive nor negative
- ($x->{sign} eq '+' && !$x->is_zero()) ? 1 : 0;
+ ($x->{sign} eq '+' && !$x->is_zero()) ? 1 : 0;
}
sub is_negative
@@ -1574,12 +1573,7 @@ sub bmuladd
# (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');
@@ -1654,7 +1648,7 @@ sub _div_inf
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();
@@ -1786,10 +1780,12 @@ sub bmod
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,@_);
@@ -1801,52 +1797,153 @@ sub bmodinv
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;
}
###############################################################################
@@ -2560,7 +2657,7 @@ sub objectify
{
$k = $a[0]->new($k);
}
- elsif (!defined $up && ref($k) ne $a[0])
+ elsif (ref($k) ne $a[0] and !defined $up || ref $k ne $up)
{
# foreign object, try to convert to integer
$k->can('as_number') ? $k = $k->as_number() : $k = $a[0]->new($k);
@@ -2640,7 +2737,7 @@ sub import
{
$_ =~ 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)
@@ -2752,93 +2849,145 @@ sub import
# 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 ($self, $str) = @_;
- my $rc = __from_hex($hs);
+ 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.
- return $self->bnan() unless defined $rc;
+ my $sign = $1;
+ my $chrs = $3;
+ $chrs =~ tr/_//d;
+ $chrs = '0' unless CORE::length $chrs;
- $rc;
- }
+ # Initialize output.
-sub from_bin
- {
- # create a bigint from a hexadecimal string
- my ($self, $bs) = @_;
+ my $x = Math::BigInt->bzero();
- my $rc = __from_bin($bs);
+ # The library method requires a prefix.
- return $self->bnan() unless defined $rc;
+ $x->{value} = $CALC->_from_hex('0x' . $chrs);
- $rc;
- }
+ # Place the sign.
-sub from_oct
- {
- # create a bigint from a hexadecimal string
- my ($self, $os) = @_;
+ if ($sign eq '-' && ! $CALC->_is_zero($x->{value})) {
+ $x->{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/;
+ 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) = @_;
- my $sign = '+'; $sign = '-' if $hs =~ /^-/;
+ 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.
- $hs =~ s/^[+-]//; # strip sign
- $x->{value} = $CALC->_from_hex($hs);
- $x->{sign} = $sign unless $CALC->_is_zero($x->{value}); # no '-0'
- $x;
- }
+ my $sign = $1;
+ my $chrs = $2;
+ $chrs =~ tr/_//d;
+ $chrs = '0' unless CORE::length $chrs;
-sub __from_bin
- {
- # internal
- # convert a (ref to) big binary string to BigInt, return undef for error
- my $bs = shift;
+ # Initialize output.
- my $x = Math::BigInt->bzero();
+ my $x = Math::BigInt->bzero();
- # strip underscores
- $bs =~ s/([01])_([01])/$1$2/g;
- $bs =~ s/([01])_([01])/$1$2/g;
- return $x->bnan() if $bs !~ /^[+-]?0b[01]+$/;
+ # The library method requires a prefix.
- my $sign = '+'; $sign = '-' if $bs =~ /^\-/;
- $bs =~ s/^[+-]//; # strip sign
+ $x->{value} = $CALC->_from_oct('0' . $chrs);
- $x->{value} = $CALC->_from_bin($bs);
- $x->{sign} = $sign unless $CALC->_is_zero($x->{value}); # no '-0'
- $x;
- }
+ # Place the sign.
+
+ 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
{
@@ -2849,7 +2998,7 @@ 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
@@ -2864,9 +3013,9 @@ 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 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
@@ -3100,7 +3249,7 @@ Math::BigInt - Arbitrary size integer/float math package
# 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:
@@ -3136,8 +3285,8 @@ Math::BigInt - Arbitrary size integer/float math package
$x->is_one('-'); # if $x is -1
$x->is_odd(); # if $x is odd
$x->is_even(); # if $x is even
- $x->is_pos(); # if $x >= 0
- $x->is_neg(); # if $x < 0
+ $x->is_pos(); # if $x > 0
+ $x->is_neg(); # if $x < 0
$x->is_inf($sign); # if $x is +inf, or -inf (sign is default '+')
$x->is_int(); # if $x is an integer (not a float)
@@ -3165,7 +3314,7 @@ Math::BigInt - Arbitrary size integer/float math package
$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)
@@ -3175,9 +3324,8 @@ Math::BigInt - Arbitrary size integer/float math package
$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
@@ -3185,7 +3333,7 @@ Math::BigInt - Arbitrary size integer/float math package
$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
$x->bxor($y); # bitwise exclusive or
@@ -3200,7 +3348,7 @@ Math::BigInt - Arbitrary size integer/float math package
$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->bround($n); # accuracy: preserve $n digits
$x->bfround($n); # $n > 0: round $nth digits,
@@ -3212,14 +3360,14 @@ Math::BigInt - Arbitrary size integer/float math package
$x->bfloor(); # return integer less or equal than $x
$x->bceil(); # return integer greater or equal than $x
-
+
# The following do not modify their arguments:
# greatest common divisor (no OO style)
my $gcd = Math::BigInt::bgcd(@values);
- # lowest common multiplicator (no OO style)
- my $lcm = Math::BigInt::blcm(@values);
-
+ # lowest common multiple (no OO style)
+ 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
@@ -3230,8 +3378,8 @@ Math::BigInt - Arbitrary size integer/float math package
$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)
+
+ # 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
@@ -3270,7 +3418,7 @@ 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
@@ -3286,7 +3434,7 @@ 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")'
@@ -3295,8 +3443,8 @@ 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:
- $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
@@ -3365,7 +3513,7 @@ 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()
@@ -3382,7 +3530,7 @@ 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
@@ -3393,15 +3541,15 @@ to the math operation as additional parameter:
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);
-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
+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
@@ -3428,7 +3576,7 @@ Math::BigInt.
# This also applies to new()!
CLASS->precision(-5); # ditto
- $P = CLASS->precision(); # read out global precision
+ $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
@@ -3443,15 +3591,15 @@ In Math::BigInt, passing a negative number precision has no effect since no
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);
-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
+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
@@ -3466,7 +3614,7 @@ Math::BigInt.
=head2 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.
@@ -3503,13 +3651,26 @@ See L<Input> for more info on accepted input formats.
$x = Math::BigInt->from_oct("0775"); # input is octal
+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.
+
=head2 from_hex()
$x = Math::BigInt->from_hex("0xcafe"); # input is hexadecimal
+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.
+
=head2 from_bin()
- $x = Math::BigInt->from_oct("0x10011"); # input is binary
+ $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.
=head2 bnan()
@@ -3553,7 +3714,6 @@ If used on an object, it will set it to one:
=head2 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
@@ -3568,7 +3728,7 @@ like:
if ($x == 0)
=head2 is_pos()/is_neg()/is_positive()/is_negative()
-
+
$x->is_pos(); # true if > 0
$x->is_neg(); # true if < 0
@@ -3605,7 +3765,7 @@ Returns -1, 0, 1 or undef.
$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()
@@ -3648,7 +3808,7 @@ numbers.
=head2 bnot()
- $x->bnot();
+ $x->bnot();
Two's complement (bitwise not). This is equivalent to
@@ -3695,19 +3855,28 @@ This method was added in v1.87 of Math::BigInt (June 2007).
=head2 bmodinv()
- num->bmodinv($mod); # modular inverse
+ $x->bmodinv($mod); # modular multiplicative inverse
+
+Returns the multiplicative inverse of C<$x> modulo C<$mod>. If
+
+ $y = $x -> copy() -> bmodinv($mod)
+
+then C<$y> is the number closest to zero, and with the same sign as C<$mod>,
+satisfying
+
+ ($x * $y) % $mod = 1 % $mod
-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>.
+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.
=head2 bmodpow()
- $num->bmodpow($exp,$mod); # modular exponentation
+ $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
@@ -3867,7 +4036,7 @@ Calculates the N'th root of C<$x>.
=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>.
@@ -3894,7 +4063,7 @@ Examples:
=head2 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.
@@ -3912,8 +4081,8 @@ does change $x in BigFloat.
=head2 blcm()
- blcm(@values); # lowest common multiplicator (no OO style)
-
+ blcm(@values); # lowest common multiple (no OO style)
+
head2 length()
$x->length();
@@ -3945,14 +4114,14 @@ Return the signed mantissa of $x as BigInt.
=head2 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()
$x->bstr();
@@ -3989,7 +4158,7 @@ This loses precision, to avoid this use L<as_int()> instead.
$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>.
@@ -4039,12 +4208,12 @@ the decimal point. For example, 123.45 has a precision of -2. 0 means an
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
@@ -4161,7 +4330,7 @@ versions <= 5.7.2) is like this:
=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
@@ -4186,7 +4355,7 @@ versions <= 5.7.2) is like this:
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.
@@ -4239,7 +4408,7 @@ This is how it works now:
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.
@@ -4301,7 +4470,7 @@ This is how it works now:
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
@@ -4414,12 +4583,12 @@ have real numbers as results, the result is NaN.
=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(); >>
@@ -4466,7 +4635,7 @@ small numbers (less than about 20 digits) and when converting very large
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
@@ -4506,7 +4675,7 @@ C<$e> and C<$m> will stay always the same, though their real values might
change.
=head1 EXAMPLES
-
+
use Math::BigInt;
sub bint { Math::BigInt->new(shift); }
@@ -4654,8 +4823,8 @@ directly.
=item *
-The private object hash keys like C<$x->{sign}> may not be changed, but
-additional keys can be added, like C<$x->{_custom}>.
+The private object hash keys like C<< $x->{sign} >> may not be changed, but
+additional keys can be added, like C<< $x->{_custom} >>.
=item *
@@ -4716,7 +4885,7 @@ As a shortcut, you can use the module C<bignum>:
use bignum;
-Also good for oneliners:
+Also good for one-liners:
perl -Mbignum -le 'print 2 ** 255'
@@ -4793,7 +4962,7 @@ So, the following examples will now work all as expected:
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;
@@ -4858,8 +5027,8 @@ 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
+
+ print scalar $c->length(),"\n"; # prints 3
=item bdiv
@@ -4870,7 +5039,7 @@ 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
@@ -4878,7 +5047,7 @@ instead.
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)
@@ -4934,8 +5103,8 @@ clearly the reasoning:
-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
@@ -4943,8 +5112,8 @@ arguments", since they wouldn't match up otherwise.
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 =
@@ -4983,7 +5152,7 @@ modify $x, the last one won't:
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.
@@ -5033,7 +5202,7 @@ the result should be a Math::BigFloat or the second operant is one.
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
@@ -5050,7 +5219,7 @@ If in doubt, break the expression into simpler terms, or cast all operands
to the desired resulting type.
Scalar values are a bit different, since:
-
+
$float = 2 + $mbf;
$float = $mbf + 2;