summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm
diff options
context:
space:
mode:
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm')
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm906
1 files changed, 479 insertions, 427 deletions
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm
index 8d7048b592..d5038f42a0 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/bigint.pm
@@ -1,10 +1,11 @@
package bigint;
-use 5.010;
use strict;
use warnings;
-our $VERSION = '0.51';
+use Carp qw< carp croak >;
+
+our $VERSION = '0.66';
use Exporter;
our @ISA = qw( Exporter );
@@ -13,99 +14,106 @@ our @EXPORT = qw( inf NaN );
use overload;
-##############################################################################
+my $obj_class = "Math::BigInt";
-# These are all alike, and thus faked by AUTOLOAD
-
-my @faked = qw/round_mode accuracy precision div_scale/;
-our ($AUTOLOAD, $_lite); # _lite for testsuite
-
-sub AUTOLOAD {
- my $name = $AUTOLOAD;
-
- $name =~ s/.*:://; # split package
- no strict 'refs';
- foreach my $n (@faked) {
- if ($n eq $name) {
- *{"bigint::$name"} =
- sub {
- my $self = shift;
- no strict 'refs';
- if (defined $_[0]) {
- return Math::BigInt->$name($_[0]);
- }
- return Math::BigInt->$name();
- };
- return &$name;
- }
- }
+##############################################################################
- # delayed load of Carp and avoid recursion
- require Carp;
- Carp::croak ("Can't call bigint\-\>$name, not a valid method");
+sub accuracy {
+ my $self = shift;
+ $obj_class -> accuracy(@_);
}
-sub upgrade {
- $Math::BigInt::upgrade;
+sub precision {
+ my $self = shift;
+ $obj_class -> precision(@_);
}
-sub _binary_constant {
- # this takes a binary/hexadecimal/octal constant string and returns it
- # as string suitable for new. Basically it converts octal to decimal, and
- # passes every thing else unmodified back.
- my $string = shift;
+sub round_mode {
+ my $self = shift;
+ $obj_class -> round_mode(@_);
+}
- return Math::BigInt->new($string) if $string =~ /^0[bx]/;
+sub div_scale {
+ my $self = shift;
+ $obj_class -> div_scale(@_);
+}
- # so it must be an octal constant
- Math::BigInt->from_oct($string);
+sub in_effect {
+ my $level = shift || 0;
+ my $hinthash = (caller($level))[10];
+ $hinthash->{bigint};
}
sub _float_constant {
- # this takes a floating point constant string and returns it truncated to
- # integer. For instance, '4.5' => '4', '1.234e2' => '123' etc
- my $float = shift;
-
- # some simple cases first
- return $float if ($float =~ /^[+-]?[0-9]+$/); # '+123','-1','0' etc
- return $float
- if ($float =~ /^[+-]?[0-9]+\.?[eE]\+?[0-9]+$/); # 123e2, 123.e+2
- return '0' if ($float =~ /^[+-]?[0]*\.[0-9]+$/); # .2, 0.2, -.1
- if ($float =~ /^[+-]?[0-9]+\.[0-9]*$/) { # 1., 1.23, -1.2 etc
- $float =~ s/\..*//;
- return $float;
- }
- my ($mis, $miv, $mfv, $es, $ev) = Math::BigInt::_split($float);
- return $float if !defined $mis; # doesn't look like a number to me
- my $ec = int($$ev);
- my $sign = $$mis;
- $sign = '' if $sign eq '+';
- if ($$es eq '-') {
- # ignore fraction part entirely
- if ($ec >= length($$miv)) { # 123.23E-4
- return '0';
+ my $str = shift;
+
+ # We can't pass input directly to new() because of the way it handles the
+ # combination of non-integers with no upgrading. Such cases are by
+ # Math::BigInt returned as NaN, but we truncate to an integer.
+
+ # See if we can convert the input string to a string using a normalized form
+ # consisting of the significand as a signed integer, the character "e", and
+ # the exponent as a signed integer, e.g., "+0e+0", "+314e-2", and "-1e+3".
+
+ my $nstr;
+
+ if (
+ # See if it is an octal number. An octal number like '0377' is also
+ # accepted by the functions parsing decimal and hexadecimal numbers, so
+ # handle octal numbers before decimal and hexadecimal numbers.
+
+ $str =~ /^0(?:[Oo]|_*[0-7])/ and
+ $nstr = Math::BigInt -> oct_str_to_dec_flt_str($str)
+
+ or
+
+ # See if it is decimal number.
+
+ $nstr = Math::BigInt -> dec_str_to_dec_flt_str($str)
+
+ or
+
+ # See if it is a hexadecimal number. Every hexadecimal number has a
+ # prefix, but the functions parsing numbers don't require it, so check
+ # to see if it actually is a hexadecimal number.
+
+ $str =~ /^0[Xx]/ and
+ $nstr = Math::BigInt -> hex_str_to_dec_flt_str($str)
+
+ or
+
+ # See if it is a binary numbers. Every binary number has a prefix, but
+ # the functions parsing numbers don't require it, so check to see if it
+ # actually is a binary number.
+
+ $str =~ /^0[Bb]/ and
+ $nstr = Math::BigInt -> bin_str_to_dec_flt_str($str))
+ {
+ my $pos = index($nstr, 'e');
+ my $expo_sgn = substr($nstr, $pos + 1, 1);
+ my $sign = substr($nstr, 0, 1);
+ my $mant = substr($nstr, 1, $pos - 1);
+ my $mant_len = CORE::length($mant);
+ my $expo = substr($nstr, $pos + 2);
+
+ if ($expo_sgn eq '-') {
+ if ($mant_len <= $expo) {
+ return $obj_class -> bzero(); # underflow
+ } else {
+ $mant = substr $mant, 0, $mant_len - $expo; # truncate
+ return $obj_class -> new($sign . $mant);
+ }
+ } else {
+ $mant .= "0" x $expo; # pad with zeros
+ return $obj_class -> new($sign . $mant);
}
- return $sign . substr($$miv, 0, length($$miv) - $ec); # 1234.45E-2 = 12
}
- # xE+y
- if ($ec >= length($$mfv)) {
- $ec -= length($$mfv);
- return $sign.$$miv.$$mfv if $ec == 0; # 123.45E+2 => 12345
- return $sign.$$miv.$$mfv.'E'.$ec; # 123.45e+3 => 12345e1
- }
- $mfv = substr($$mfv, 0, $ec);
- $sign.$$miv.$mfv; # 123.45e+1 => 1234
-}
-sub unimport {
- $^H{bigint} = undef; # no longer in effect
- overload::remove_constant('binary', '', 'float', '', 'integer');
-}
+ # If we get here, there is a bug in the code above this point.
-sub in_effect {
- my $level = shift || 0;
- my $hinthash = (caller($level))[10];
- $hinthash->{bigint};
+ warn "Internal error: unable to handle literal constant '$str'.",
+ " This is a bug, so please report this to the module author.";
+ return $obj_class -> bnan();
}
#############################################################################
@@ -122,13 +130,13 @@ sub _hex_core {
# Strip off, clean, and parse as much as we can from the beginning.
my $x;
- if ($str =~ s/ ^ (0?[xX])? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) {
+ if ($str =~ s/ ^ ( 0? [xX] )? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) {
my $chrs = $2;
$chrs =~ tr/_//d;
$chrs = '0' unless CORE::length $chrs;
- $x = Math::BigInt -> from_hex($chrs);
+ $x = $obj_class -> from_hex($chrs);
} else {
- $x = Math::BigInt -> bzero();
+ $x = $obj_class -> bzero();
}
# Warn about trailing garbage.
@@ -162,11 +170,11 @@ sub _oct_core {
# Strip off, clean, and parse as much as we can from the beginning.
- if ($str =~ s/ ^ (0?[bB])? ( [01]* ( _ [01]+ )* ) //x) {
+ if ($str =~ s/ ^ ( 0? [bB] )? ( [01]* ( _ [01]+ )* ) //x) {
my $chrs = $2;
$chrs =~ tr/_//d;
$chrs = '0' unless CORE::length $chrs;
- $x = Math::BigInt -> from_bin($chrs);
+ $x = $obj_class -> from_bin($chrs);
}
# Warn about trailing garbage.
@@ -183,21 +191,20 @@ sub _oct_core {
# Octal input. Strip off, clean, and parse as much as we can from the
# beginning.
- if ($str =~ s/ ^ ( [0-7]* ( _ [0-7]+ )* ) //x) {
- my $chrs = $1;
+ if ($str =~ s/ ^ ( 0? [oO] )? ( [0-7]* ( _ [0-7]+ )* ) //x) {
+ my $chrs = $2;
$chrs =~ tr/_//d;
$chrs = '0' unless CORE::length $chrs;
- $x = Math::BigInt -> from_oct($chrs);
+ $x = $obj_class -> from_oct($chrs);
}
- # Warn about trailing garbage. CORE::oct() only warns about 8 and 9.
+ # Warn about trailing garbage. CORE::oct() only warns about 8 and 9, but it
+ # is more helpful to warn about all invalid digits.
if (CORE::length($str)) {
- my $chr = substr($str, 0, 1);
- if ($chr eq '8' || $chr eq '9') {
- require Carp;
- Carp::carp(sprintf("Illegal octal digit '%s' ignored", $chr));
- }
+ require Carp;
+ Carp::carp(sprintf("Illegal octal digit '%s' ignored",
+ substr($str, 0, 1)));
}
return $x;
@@ -228,16 +235,20 @@ my ($prev_oct, $prev_hex, $overridden);
if (LEXICAL) { eval <<'.' }
sub _hex(_) {
my $hh = (caller 0)[10];
- return $prev_hex ? &$prev_hex($_[0]) : CORE::hex($_[0])
- unless $$hh{bigint}||$$hh{bignum}||$$hh{bigrat};
- _hex_core($_[0]);
+ return $$hh{bigint} ? bigint::_hex_core($_[0])
+ : $$hh{bigfloat} ? bigfloat::_hex_core($_[0])
+ : $$hh{bigrat} ? bigrat::_hex_core($_[0])
+ : $prev_hex ? &$prev_hex($_[0])
+ : CORE::hex($_[0]);
}
sub _oct(_) {
my $hh = (caller 0)[10];
- return $prev_oct ? &$prev_oct($_[0]) : CORE::oct($_[0])
- unless $$hh{bigint}||$$hh{bignum}||$$hh{bigrat};
- _oct_core($_[0]);
+ return $$hh{bigint} ? bigint::_oct_core($_[0])
+ : $$hh{bigfloat} ? bigfloat::_oct_core($_[0])
+ : $$hh{bigrat} ? bigrat::_oct_core($_[0])
+ : $prev_oct ? &$prev_oct($_[0])
+ : CORE::oct($_[0]);
}
.
@@ -248,128 +259,141 @@ sub _override {
no warnings 'redefine';
*CORE::GLOBAL::oct = \&_oct;
*CORE::GLOBAL::hex = \&_hex;
- $overridden++;
+ $overridden = 1;
+}
+
+sub unimport {
+ $^H{bigint} = undef; # no longer in effect
+ overload::remove_constant('binary', '', 'float', '', 'integer');
}
sub import {
- my $self = shift;
+ my $class = shift;
- $^H{bigint} = 1; # we are in effect
+ $^H{bigint} = 1; # we are in effect
+ $^H{bigfloat} = undef;
+ $^H{bigrat} = undef;
# for newer Perls always override hex() and oct() with a lexical version:
if (LEXICAL) {
_override();
}
- # some defaults
- my $lib = '';
- my $lib_kind = 'try';
-
- my @import = (':constant'); # drive it w/ constant
- my @a = @_;
- my $l = scalar @_;
- my $j = 0;
- my ($ver, $trace); # version? trace?
- my ($a, $p); # accuracy, precision
- for (my $i = 0; $i < $l; $i++, $j++) {
- if ($_[$i] =~ /^(l|lib|try|only)$/) {
- # this causes a different low lib to take care...
- $lib_kind = $1;
- $lib_kind = 'lib' if $lib_kind eq 'l';
- $lib = $_[$i + 1] || '';
- my $s = 2;
- $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..."
- splice @a, $j, $s;
- $j -= $s;
- $i++;
- } elsif ($_[$i] =~ /^(a|accuracy)$/) {
- $a = $_[$i + 1];
- my $s = 2;
- $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..."
- splice @a, $j, $s;
- $j -= $s;
- $i++;
- } elsif ($_[$i] =~ /^(p|precision)$/) {
- $p = $_[$i + 1];
- my $s = 2;
- $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..."
- splice @a, $j, $s;
- $j -= $s;
- $i++;
- } elsif ($_[$i] =~ /^(v|version)$/) {
+
+ my @import = ();
+ my @a = (); # unrecognized arguments
+ my $ver; # version? trace?
+
+ while (@_) {
+ my $param = shift;
+
+ # Accuracy.
+
+ if ($param =~ /^a(ccuracy)?$/) {
+ push @import, 'accuracy', shift();
+ next;
+ }
+
+ # Precision.
+
+ if ($param =~ /^p(recision)?$/) {
+ push @import, 'precision', shift();
+ next;
+ }
+
+ # Rounding mode.
+
+ if ($param eq 'round_mode') {
+ push @import, 'round_mode', shift();
+ next;
+ }
+
+ # Backend library.
+
+ if ($param =~ /^(l|lib|try|only)$/) {
+ push @import, $param eq 'l' ? 'lib' : $param;
+ push @import, shift() if @_;
+ next;
+ }
+
+ if ($param =~ /^(v|version)$/) {
$ver = 1;
- splice @a, $j, 1;
- $j--;
- } elsif ($_[$i] =~ /^(t|trace)$/) {
- $trace = 1;
- splice @a, $j, 1;
- $j--;
- } elsif ($_[$i] !~ /^(PI|e|bpi|bexp|hex|oct)\z/) {
- die ("unknown option $_[$i]");
+ next;
}
- }
- my $class;
- $_lite = 0; # using M::BI::L ?
- if ($trace) {
- require Math::BigInt::Trace;
- $class = 'Math::BigInt::Trace';
- } else {
- # see if we can find Math::BigInt::Lite
- if (!defined $a && !defined $p) { # rounding won't work to well
- local @INC = @INC;
- pop @INC if $INC[-1] eq '.';
- if (eval { require Math::BigInt::Lite; 1 }) {
- @import = (); # :constant in Lite, not MBI
- Math::BigInt::Lite->import(':constant');
- $_lite = 1; # signal okay
- }
+
+ if ($param =~ /^(t|trace)$/) {
+ $obj_class .= "::Trace";
+ eval "require $obj_class";
+ die $@ if $@;
+ next;
+ }
+
+ if ($param =~ /^(PI|e|bexp|bpi|hex|oct)\z/) {
+ push @a, $param;
+ next;
}
- require Math::BigInt if $_lite == 0; # not already loaded?
- $class = 'Math::BigInt'; # regardless of MBIL or not
+
+ croak("Unknown option '$param'");
}
- push @import, $lib_kind => $lib if $lib ne '';
- # Math::BigInt::Trace or plain Math::BigInt
- $class->import(@import);
- bigint->accuracy($a) if defined $a;
- bigint->precision($p) if defined $p;
+ eval "require $obj_class";
+ die $@ if $@;
+ $obj_class -> import(@import);
+
if ($ver) {
- print "bigint\t\t\t v$VERSION\n";
- print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
- print "Math::BigInt\t\t v$Math::BigInt::VERSION";
- my $config = Math::BigInt->config();
- print " lib => $config->{lib} v$config->{lib_version}\n";
+ printf "%-31s v%s\n", $class, $class -> VERSION();
+ printf " lib => %-23s v%s\n",
+ $obj_class -> config("lib"), $obj_class -> config("lib_version");
+ printf "%-31s v%s\n", $obj_class, $obj_class -> VERSION();
exit;
}
- # we take care of floating point constants, since BigFloat isn't available
- # and BigInt doesn't like them:
- overload::constant float =>
- sub {
- Math::BigInt->new(_float_constant(shift));
- };
- # Take care of octal/hexadecimal constants
- overload::constant binary =>
- sub {
- _binary_constant(shift);
- };
- # if another big* was already loaded:
- my ($package) = caller();
+ $class -> export_to_level(1, $class, @a); # export inf, NaN, etc.
- no strict 'refs';
- if (!defined *{"${package}::inf"}) {
- $self->export_to_level(1, $self, @a); # export inf and NaN, e and PI
- }
+ overload::constant
+
+ # This takes care each number written as decimal integer and within the
+ # range of what perl can represent as an integer, e.g., "314", but not
+ # "3141592653589793238462643383279502884197169399375105820974944592307".
+
+ integer => sub {
+ #printf "Value '%s' handled by the 'integer' sub.\n", $_[0];
+ my $str = shift;
+ return $obj_class -> new($str);
+ },
+
+ # This takes care of each number written with a decimal point and/or
+ # using floating point notation, e.g., "3.", "3.0", "3.14e+2" (decimal),
+ # "0b1.101p+2" (binary), "03.14p+2" and "0o3.14p+2" (octal), and
+ # "0x3.14p+2" (hexadecimal).
+
+ float => sub {
+ #printf "# Value '%s' handled by the 'float' sub.\n", $_[0];
+ _float_constant(shift);
+ },
+
+ # Take care of each number written as an integer (no decimal point or
+ # exponent) using binary, octal, or hexadecimal notation, e.g., "0b101"
+ # (binary), "0314" and "0o314" (octal), and "0x314" (hexadecimal).
+
+ binary => sub {
+ #printf "# Value '%s' handled by the 'binary' sub.\n", $_[0];
+ my $str = shift;
+ return $obj_class -> new($str) if $str =~ /^0[XxBb]/;
+ $obj_class -> from_oct($str);
+ };
}
-sub inf () { Math::BigInt->binf(); }
-sub NaN () { Math::BigInt->bnan(); }
+sub inf () { $obj_class -> binf(); }
+sub NaN () { $obj_class -> bnan(); }
+
+sub PI () { $obj_class -> new(3); }
+sub e () { $obj_class -> new(2); }
+
+sub bpi ($) { $obj_class -> new(3); }
-sub PI () { Math::BigInt->new(3); }
-sub e () { Math::BigInt->new(2); }
-sub bpi ($) { Math::BigInt->new(3); }
sub bexp ($$) {
- my $x = Math::BigInt->new($_[0]);
- $x->bexp($_[1]);
+ my $x = $obj_class -> new(shift);
+ $x -> bexp(@_);
}
1;
@@ -380,66 +404,104 @@ __END__
=head1 NAME
-bigint - Transparent BigInteger support for Perl
+bigint - transparent big integer support for Perl
=head1 SYNOPSIS
- use bigint;
+ use bigint;
- $x = 2 + 4.5,"\n"; # BigInt 6
- print 2 ** 512,"\n"; # really is what you think it is
- print inf + 42,"\n"; # inf
- print NaN * 7,"\n"; # NaN
- print hex("0x1234567890123490"),"\n"; # Perl v5.10.0 or later
+ $x = 2 + 4.5; # Math::BigInt 6
+ print 2 ** 512; # Math::BigInt 134...096
+ print inf + 42; # Math::BigInt inf
+ print NaN * 7; # Math::BigInt NaN
+ print hex("0x1234567890123490"); # Perl v5.10.0 or later
- {
- no bigint;
- print 2 ** 256,"\n"; # a normal Perl scalar now
- }
+ {
+ no bigint;
+ print 2 ** 256; # a normal Perl scalar now
+ }
- # Import into current package:
- use bigint qw/hex oct/;
- print hex("0x1234567890123490"),"\n";
- print oct("01234567890123490"),"\n";
+ # for older Perls, import into current package:
+ use bigint qw/hex oct/;
+ print hex("0x1234567890123490");
+ print oct("01234567890123490");
=head1 DESCRIPTION
+All numeric literal in the given scope are converted to Math::BigInt objects.
+Numeric literal that represent non-integers are truncated to an integer. All
+results of expressions are also truncated to integer.
+
All operators (including basic math operations) except the range operator C<..>
-are overloaded. Integer constants are created as proper BigInts.
+are overloaded.
+
+Unlike the L<integer> pragma, the C<bigint> pragma creates integers that are
+only limited in their size by the available memory.
+
+So, the following:
+
+ use bigint;
+ $x = 1234;
+
+creates a Math::BigInt and stores a reference to in $x. This happens
+transparently and behind your back, so to speak.
+
+You can see this with the following:
+
+ perl -Mbigint -le 'print ref(1234)'
+
+Since numbers are actually objects, you can call all the usual methods from
+Math::BigFloat on them. This even works to some extent on expressions:
+
+ perl -Mbigint -le '$x = 1234; print $x->bdec()'
+ perl -Mbigint -le 'print 1234->copy()->binc();'
+ perl -Mbigint -le 'print 1234->copy()->binc->badd(6);'
+ perl -Mbigint -le 'print +(1234)->copy()->binc()'
+
+(Note that print doesn't do what you expect if the expression starts with
+'(' hence the C<+>)
+
+You can even chain the operations together as usual:
-Floating point constants are truncated to integer. All parts and results of
-expressions are also truncated.
+ perl -Mbigint -le 'print 1234->copy()->binc->badd(6);'
+ 1241
-Unlike L<integer>, this pragma creates integer constants that are only
-limited in their size by the available memory and CPU time.
+Please note the following does not work as expected (prints nothing), since
+overloading of '..' is not yet possible in Perl (as of v5.8.0):
+
+ perl -Mbigint -le 'for (1..2) { print ref($_); }'
=head2 use integer vs. use bigint
-There is one small difference between C<use integer> and C<use bigint>: the
-former will not affect assignments to variables and the return value of
-some functions. C<bigint> truncates these results to integer too:
-
- # perl -Minteger -wle 'print 3.2'
- 3.2
- # perl -Minteger -wle 'print 3.2 + 0'
- 3
- # perl -Mbigint -wle 'print 3.2'
- 3
- # perl -Mbigint -wle 'print 3.2 + 0'
- 3
-
- # perl -Mbigint -wle 'print exp(1) + 0'
- 2
- # perl -Mbigint -wle 'print exp(1)'
- 2
- # perl -Minteger -wle 'print exp(1)'
- 2.71828182845905
- # perl -Minteger -wle 'print exp(1) + 0'
- 2
-
-In practice this makes seldom a difference as B<parts and results> of
-expressions will be truncated anyway, but this can, for instance, affect the
-return value of subroutines:
+There are some difference between C<use integer> and C<use bigint>.
+
+Whereas C<use integer> is limited to what can be handled as a Perl scalar, C<use
+bigint> can handle arbitrarily large integers.
+
+Also, C<use integer> does affect assignments to variables and the return value
+of some functions. C<use bigint> truncates these results to integer:
+
+ # perl -Minteger -wle 'print 3.2'
+ 3.2
+ # perl -Minteger -wle 'print 3.2 + 0'
+ 3
+ # perl -Mbigint -wle 'print 3.2'
+ 3
+ # perl -Mbigint -wle 'print 3.2 + 0'
+ 3
+
+ # perl -Mbigint -wle 'print exp(1) + 0'
+ 2
+ # perl -Mbigint -wle 'print exp(1)'
+ 2
+ # perl -Minteger -wle 'print exp(1)'
+ 2.71828182845905
+ # perl -Minteger -wle 'print exp(1) + 0'
+ 2
+
+In practice this seldom makes a difference for small integers as B<parts and
+results> of expressions are truncated anyway, but this can, for instance, affect
+the return value of subroutines:
sub three_integer { use integer; return 3.2; }
sub three_bigint { use bigint; return 3.2; }
@@ -448,168 +510,135 @@ return value of subroutines:
=head2 Options
-bigint recognizes some options that can be passed while loading it via use.
-The options can (currently) be either a single letter form, or the long form.
-The following options exist:
+C<bigint> recognizes some options that can be passed while loading it via
+C<use>. The following options exist:
-=over 2
+=over 4
=item a or accuracy
This sets the accuracy for all math operations. The argument must be greater
-than or equal to zero. See Math::BigInt's bround() function for details.
+than or equal to zero. See Math::BigInt's bround() method for details.
- perl -Mbigint=a,2 -le 'print 12345+1'
+ perl -Mbigint=a,2 -le 'print 12345+1'
Note that setting precision and accuracy at the same time is not possible.
=item p or precision
This sets the precision for all math operations. The argument can be any
-integer. Negative values mean a fixed number of digits after the dot, and
-are <B>ignored</B> since all operations happen in integer space.
-A positive value rounds to this digit left from the dot. 0 or 1 mean round to
-integer and are ignore like negative values.
-
-See Math::BigInt's bfround() function for details.
+integer. Negative values mean a fixed number of digits after the dot, and are
+ignored since all operations happen in integer space. A positive value rounds to
+this digit left from the dot. 0 means round to integer. See Math::BigInt's
+bfround() method for details.
- perl -Mbignum=p,5 -le 'print 123456789+123'
+ perl -mbigint=p,5 -le 'print 123456789+123'
Note that setting precision and accuracy at the same time is not possible.
=item t or trace
-This enables a trace mode and is primarily for debugging bigint or
-Math::BigInt.
-
-=item hex
-
-Override the built-in hex() method with a version that can handle big
-integers. This overrides it by exporting it to the current package. Under
-Perl v5.10.0 and higher, this is not so necessary, as hex() is lexically
-overridden in the current scope whenever the bigint pragma is active.
-
-=item oct
+This enables a trace mode and is primarily for debugging.
-Override the built-in oct() method with a version that can handle big
-integers. This overrides it by exporting it to the current package. Under
-Perl v5.10.0 and higher, this is not so necessary, as oct() is lexically
-overridden in the current scope whenever the bigint pragma is active.
-
-=item l, lib, try or only
+=item l, lib, try, or only
Load a different math lib, see L<Math Library>.
- perl -Mbigint=lib,GMP -e 'print 2 ** 512'
- perl -Mbigint=try,GMP -e 'print 2 ** 512'
- perl -Mbigint=only,GMP -e 'print 2 ** 512'
+ perl -Mbigint=l,GMP -e 'print 2 ** 512'
+ perl -Mbigint=lib,GMP -e 'print 2 ** 512'
+ perl -Mbigint=try,GMP -e 'print 2 ** 512'
+ perl -Mbigint=only,GMP -e 'print 2 ** 512'
+
+=item hex
-Currently there is no way to specify more than one library on the command
-line. This means the following does not work:
+Override the built-in hex() method with a version that can handle big numbers.
+This overrides it by exporting it to the current package. Under Perl v5.10.0 and
+higher, this is not necessary, as hex() is lexically overridden in the current
+scope whenever the C<bigint> pragma is active.
- perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
+=item oct
-This will be hopefully fixed soon ;)
+Override the built-in oct() method with a version that can handle big numbers.
+This overrides it by exporting it to the current package. Under Perl v5.10.0 and
+higher, this is not so necessary, as oct() is lexically overridden in the
+current scope whenever the C<bigint> pragma is active.
=item v or version
-This prints out the name and version of all modules used and then exits.
+this prints out the name and version of the modules and then exits.
- perl -Mbigint=v
+ perl -Mbigint=v
=back
=head2 Math Library
-Math with the numbers is done (by default) by a module called
-Math::BigInt::Calc. This is equivalent to saying:
+Math with the numbers is done (by default) by a backend library module called
+Math::BigInt::Calc. The default is equivalent to saying:
- use bigint lib => 'Calc';
+ use bigint lib => 'Calc';
-You can change this by using:
+you can change this by using:
- use bignum lib => 'GMP';
+ use bigint lib => 'GMP';
-The following would first try to find Math::BigInt::Foo, then
-Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
+The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar,
+and if this also fails, revert to Math::BigInt::Calc:
- use bigint lib => 'Foo,Math::BigInt::Bar';
+ use bigint lib => 'Foo,Math::BigInt::Bar';
-Using C<lib> warns if none of the specified libraries can be found and
-L<Math::BigInt> did fall back to one of the default libraries.
-To suppress this warning, use C<try> instead:
+Using c<lib> warns if none of the specified libraries can be found and
+L<Math::BigInt> fell back to one of the default libraries. To suppress this
+warning, use c<try> instead:
- use bignum try => 'GMP';
+ use bigint try => 'GMP';
If you want the code to die instead of falling back, use C<only> instead:
- use bignum only => 'GMP';
-
-Please see respective module documentation for further details.
-
-=head2 Internal Format
-
-The numbers are stored as objects, and their internals might change at anytime,
-especially between math operations. The objects also might belong to different
-classes, like Math::BigInt, or Math::BigInt::Lite. Mixing them together, even
-with normal scalars is not extraordinary, but normal and expected.
+ use bigint only => 'GMP';
-You should not depend on the internal format, all accesses must go through
-accessor methods. E.g. looking at $x->{sign} is not a good idea since there
-is no guaranty that the object in question has such a hash key, nor is a hash
-underneath at all.
-
-=head2 Sign
-
-The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
-You can access it with the sign() method.
-
-A sign of 'NaN' is used to represent the result when input arguments are not
-numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
-minus infinity. You will get '+inf' when dividing a positive number by 0, and
-'-inf' when dividing any negative number by 0.
+Please see the respective module documentation for further details.
=head2 Method calls
-Since all numbers are now objects, you can use all functions that are part of
-the BigInt API. You can only use the bxxx() notation, and not the fxxx()
-notation, though.
+Since all numbers are now objects, you can use all methods that are part of the
+Math::BigInt API.
But a warning is in order. When using the following to make a copy of a number,
only a shallow copy will be made.
- $x = 9; $y = $x;
- $x = $y = 7;
+ $x = 9; $y = $x;
+ $x = $y = 7;
-Using the copy or the original with overloaded math is okay, e.g. the
-following work:
+Using the copy or the original with overloaded math is okay, e.g., the following
+work:
- $x = 9; $y = $x;
- print $x + 1, " ", $y,"\n"; # prints 10 9
+ $x = 9; $y = $x;
+ print $x + 1, " ", $y,"\n"; # prints 10 9
-but calling any method that modifies the number directly will result in
-B<both> the original and the copy being destroyed:
+but calling any method that modifies the number directly will result in B<both>
+the original and the copy being destroyed:
- $x = 9; $y = $x;
- print $x->badd(1), " ", $y,"\n"; # prints 10 10
+ $x = 9; $y = $x;
+ print $x->badd(1), " ", $y,"\n"; # prints 10 10
- $x = 9; $y = $x;
- print $x->binc(1), " ", $y,"\n"; # prints 10 10
+ $x = 9; $y = $x;
+ print $x->binc(1), " ", $y,"\n"; # prints 10 10
- $x = 9; $y = $x;
- print $x->bmul(2), " ", $y,"\n"; # prints 18 18
+ $x = 9; $y = $x;
+ print $x->bmul(2), " ", $y,"\n"; # prints 18 18
Using methods that do not modify, but test that the contents works:
- $x = 9; $y = $x;
- $z = 9 if $x->is_zero(); # works fine
+ $x = 9; $y = $x;
+ $z = 9 if $x->is_zero(); # works fine
-See the documentation about the copy constructor and C<=> in overload, as
-well as the documentation in BigInt for further details.
+See the documentation about the copy constructor and C<=> in overload, as well
+as the documentation in Math::BigInt for further details.
=head2 Methods
-=over 2
+=over 4
=item inf()
@@ -623,56 +652,66 @@ handle bareword C<NaN> properly.
=item e
- # perl -Mbigint=e -wle 'print e'
+ # perl -Mbigint=e -wle 'print e'
-Returns Euler's number C<e>, aka exp(1). Note that under bigint, this is
-truncated to an integer, and hence simple '2'.
+Returns Euler's number C<e>, aka exp(1). Note that under C<bigint>, this is
+truncated to an integer, i.e., 2.
=item PI
- # perl -Mbigint=PI -wle 'print PI'
+ # perl -Mbigint=PI -wle 'print PI'
-Returns PI. Note that under bigint, this is truncated to an integer, and hence
-simple '3'.
+Returns PI. Note that under C<bigint>, this is truncated to an integer, i.e., 3.
=item bexp()
- bexp($power,$accuracy);
+ bexp($power, $accuracy);
-Returns Euler's number C<e> raised to the appropriate power, to
-the wanted accuracy.
+Returns Euler's number C<e> raised to the appropriate power, to the wanted
+accuracy.
-Note that under bigint, the result is truncated to an integer.
+Note that under C<bigint>, the result is truncated to an integer.
Example:
- # perl -Mbigint=bexp -wle 'print bexp(1,80)'
+ # perl -Mbigint=bexp -wle 'print bexp(1,80)'
=item bpi()
- bpi($accuracy);
+ bpi($accuracy);
-Returns PI to the wanted accuracy. Note that under bigint, this is truncated
-to an integer, and hence simple '3'.
+Returns PI to the wanted accuracy. Note that under C<bigint>, this is truncated
+to an integer, i.e., 3.
Example:
- # perl -Mbigint=bpi -wle 'print bpi(80)'
+ # perl -Mbigint=bpi -wle 'print bpi(80)'
+
+=item accuracy()
+
+Set or get the accuracy.
+
+=item precision()
+
+Set or get the precision.
+
+=item round_mode()
+
+Set or get the rounding mode.
-=item upgrade()
+=item div_scale()
-Return the class that numbers are upgraded to, is in fact returning
-C<$Math::BigInt::upgrade>.
+Set or get the division scale.
=item in_effect()
- use bigint;
+ use bigint;
- print "in effect\n" if bigint::in_effect; # true
- {
- no bigint;
- print "in effect\n" if bigint::in_effect; # false
- }
+ print "in effect\n" if bigint::in_effect; # true
+ {
+ no bigint;
+ print "in effect\n" if bigint::in_effect; # false
+ }
Returns true or false if C<bigint> is in effect in the current scope.
@@ -682,41 +721,47 @@ This method only works on Perl v5.9.4 or later.
=head1 CAVEATS
-=over 2
+=over 4
+
+=item Hexadecimal, octal, and binary floating point literals
+
+Perl (and this module) accepts hexadecimal, octal, and binary floating point
+literals, but use them with care with Perl versions before v5.32.0, because some
+versions of Perl silently give the wrong result.
=item Operator vs literal overloading
-C<bigint> works by overloading handling of integer and floating point
-literals, converting them to L<Math::BigInt> objects.
+C<bigint> works by overloading handling of integer and floating point literals,
+converting them to L<Math::BigInt> objects.
-This means that arithmetic involving only string values or string
-literals will be performed using Perl's built-in operators.
+This means that arithmetic involving only string values or string literals are
+performed using Perl's built-in operators.
For example:
- use bignum;
+ use bigint;
my $x = "900000000000000009";
my $y = "900000000000000007";
print $x - $y;
-will output C<0> on default 32-bit builds, since C<bigint> never sees
-the string literals. To ensure the expression is all treated as
-C<Math::BigInt> objects, use a literal number in the expression:
+outputs C<0> on default 32-bit builds, since C<bigint> never sees the string
+literals. To ensure the expression is all treated as C<Math::BigInt> objects,
+use a literal number in the expression:
print +(0+$x) - $y;
-=item ranges
+=item Ranges
-Perl does not allow overloading of ranges, so you can neither safely use
-ranges with bigint endpoints, nor is the iterator variable a bigint.
+Perl does not allow overloading of ranges, so you can neither safely use ranges
+with C<bigint> endpoints, nor is the iterator variable a C<Math::BigInt>.
- use 5.010;
- for my $i (12..13) {
- for my $j (20..21) {
- say $i ** $j; # produces a floating-point number,
- # not a big integer
- }
- }
+ use 5.010;
+ for my $i (12..13) {
+ for my $j (20..21) {
+ say $i ** $j; # produces a floating-point number,
+ # not an object
+ }
+ }
=item in_effect()
@@ -724,63 +769,49 @@ This method only works on Perl v5.9.4 or later.
=item hex()/oct()
-C<bigint> overrides these routines with versions that can also handle
-big integer values. Under Perl prior to version v5.9.4, however, this
-will not happen unless you specifically ask for it with the two
-import tags "hex" and "oct" - and then it will be global and cannot be
-disabled inside a scope with "no bigint":
+C<bigint> overrides these routines with versions that can also handle big
+integer values. Under Perl prior to version v5.9.4, however, this will not
+happen unless you specifically ask for it with the two import tags "hex" and
+"oct" - and then it will be global and cannot be disabled inside a scope with
+C<no bigint>:
- use bigint qw/hex oct/;
+ use bigint qw/hex oct/;
+ print hex("0x1234567890123456");
+ {
+ no bigint;
print hex("0x1234567890123456");
- {
- no bigint;
- print hex("0x1234567890123456");
- }
+ }
The second call to hex() will warn about a non-portable constant.
Compare this to:
- use bigint;
+ use bigint;
- # will warn only under Perl older than v5.9.4
- print hex("0x1234567890123456");
+ # will warn only under Perl older than v5.9.4
+ print hex("0x1234567890123456");
=back
-=head1 MODULES USED
-
-C<bigint> is just a thin wrapper around various modules of the Math::BigInt
-family. Think of it as the head of the family, who runs the shop, and orders
-the others to do the work.
-
-The following modules are currently used by bigint:
-
- Math::BigInt::Lite (for speed, and only if it is loadable)
- Math::BigInt
-
=head1 EXAMPLES
Some cool command line examples to impress the Python crowd ;) You might want
-to compare them to the results under -Mbignum or -Mbigrat:
-
- perl -Mbigint -le 'print sqrt(33)'
- perl -Mbigint -le 'print 2*255'
- perl -Mbigint -le 'print 4.5+2*255'
- perl -Mbigint -le 'print 3/7 + 5/7 + 8/3'
- perl -Mbigint -le 'print 123->is_odd()'
- perl -Mbigint -le 'print log(2)'
- perl -Mbigint -le 'print 2 ** 0.5'
- perl -Mbigint=a,65 -le 'print 2 ** 0.2'
- perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777'
+to compare them to the results under -Mbigfloat or -Mbigrat:
-=head1 BUGS
+ perl -Mbigint -le 'print sqrt(33)'
+ perl -Mbigint -le 'print 2**255'
+ perl -Mbigint -le 'print 4.5+2**255'
+ perl -Mbigint -le 'print 123->is_odd()'
+ perl -Mbigint=l,GMP -le 'print 7 ** 7777'
-For information about bugs and how to report them, see the BUGS section in the
-documentation available with the perldoc command.
+=head1 BUGS
- perldoc bignum
+Please report any bugs or feature requests to
+C<bug-bignum at rt.cpan.org>, or through the web interface at
+L<https://rt.cpan.org/Ticket/Create.html?Queue=bignum> (requires login).
+We will be notified, and then you'll automatically be notified of
+progress on your bug as I make changes.
=head1 SUPPORT
@@ -788,10 +819,31 @@ You can find documentation for this module with the perldoc command.
perldoc bigint
-For more information, see the SUPPORT section in the documentation available
-with the perldoc command.
+You can also look for information at:
+
+=over 4
+
+=item * GitHub
+
+L<https://github.com/pjacklam/p5-bignum>
- perldoc bignum
+=item * RT: CPAN's request tracker
+
+L<https://rt.cpan.org/Dist/Display.html?Name=bignum>
+
+=item * MetaCPAN
+
+L<https://metacpan.org/release/bignum>
+
+=item * CPAN Testers Matrix
+
+L<http://matrix.cpantesters.org/?dist=bignum>
+
+=item * CPAN Ratings
+
+L<https://cpanratings.perl.org/dist/bignum>
+
+=back
=head1 LICENSE
@@ -815,7 +867,7 @@ L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
=item *
-Maintained by Peter John Acklam E<lt>pjacklam@gmail.com<gt>, 2014-.
+Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-.
=back