Blame lib/bigint.pm

Packit 7e8a16
package bigint;
Packit 7e8a16
Packit 7e8a16
use 5.010;
Packit 7e8a16
use strict;
Packit 7e8a16
use warnings;
Packit 7e8a16
Packit 7e8a16
our $VERSION = '0.49';
Packit 7e8a16
Packit 7e8a16
use Exporter;
Packit 7e8a16
our @ISA            = qw( Exporter );
Packit 7e8a16
our @EXPORT_OK      = qw( PI e bpi bexp hex oct );
Packit 7e8a16
our @EXPORT         = qw( inf NaN );
Packit 7e8a16
Packit 7e8a16
use overload;
Packit 7e8a16
Packit 7e8a16
##############################################################################
Packit 7e8a16
Packit 7e8a16
# These are all alike, and thus faked by AUTOLOAD
Packit 7e8a16
Packit 7e8a16
my @faked = qw/round_mode accuracy precision div_scale/;
Packit 7e8a16
our ($AUTOLOAD, $_lite);        # _lite for testsuite
Packit 7e8a16
Packit 7e8a16
sub AUTOLOAD {
Packit 7e8a16
    my $name = $AUTOLOAD;
Packit 7e8a16
Packit 7e8a16
    $name =~ s/.*:://;          # split package
Packit 7e8a16
    no strict 'refs';
Packit 7e8a16
    foreach my $n (@faked) {
Packit 7e8a16
        if ($n eq $name) {
Packit 7e8a16
            *{"bigint::$name"} =
Packit 7e8a16
              sub {
Packit 7e8a16
                  my $self = shift;
Packit 7e8a16
                  no strict 'refs';
Packit 7e8a16
                  if (defined $_[0]) {
Packit 7e8a16
                      return Math::BigInt->$name($_[0]);
Packit 7e8a16
                  }
Packit 7e8a16
                  return Math::BigInt->$name();
Packit 7e8a16
              };
Packit 7e8a16
            return &$name;
Packit 7e8a16
        }
Packit 7e8a16
    }
Packit 7e8a16
Packit 7e8a16
    # delayed load of Carp and avoid recursion
Packit 7e8a16
    require Carp;
Packit 7e8a16
    Carp::croak ("Can't call bigint\-\>$name, not a valid method");
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub upgrade {
Packit 7e8a16
    $Math::BigInt::upgrade;
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub _binary_constant {
Packit 7e8a16
    # this takes a binary/hexadecimal/octal constant string and returns it
Packit 7e8a16
    # as string suitable for new. Basically it converts octal to decimal, and
Packit 7e8a16
    # passes every thing else unmodified back.
Packit 7e8a16
    my $string = shift;
Packit 7e8a16
Packit 7e8a16
    return Math::BigInt->new($string) if $string =~ /^0[bx]/;
Packit 7e8a16
Packit 7e8a16
    # so it must be an octal constant
Packit 7e8a16
    Math::BigInt->from_oct($string);
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub _float_constant {
Packit 7e8a16
    # this takes a floating point constant string and returns it truncated to
Packit 7e8a16
    # integer. For instance, '4.5' => '4', '1.234e2' => '123' etc
Packit 7e8a16
    my $float = shift;
Packit 7e8a16
Packit 7e8a16
    # some simple cases first
Packit 7e8a16
    return $float if ($float =~ /^[+-]?[0-9]+$/);       # '+123','-1','0' etc
Packit 7e8a16
    return $float
Packit 7e8a16
      if ($float =~ /^[+-]?[0-9]+\.?[eE]\+?[0-9]+$/);   # 123e2, 123.e+2
Packit 7e8a16
    return '0' if ($float =~ /^[+-]?[0]*\.[0-9]+$/);    # .2, 0.2, -.1
Packit 7e8a16
    if ($float =~ /^[+-]?[0-9]+\.[0-9]*$/) {            # 1., 1.23, -1.2 etc
Packit 7e8a16
        $float =~ s/\..*//;
Packit 7e8a16
        return $float;
Packit 7e8a16
    }
Packit 7e8a16
    my ($mis, $miv, $mfv, $es, $ev) = Math::BigInt::_split($float);
Packit 7e8a16
    return $float if !defined $mis;       # doesn't look like a number to me
Packit 7e8a16
    my $ec = int($$ev);
Packit 7e8a16
    my $sign = $$mis;
Packit 7e8a16
    $sign = '' if $sign eq '+';
Packit 7e8a16
    if ($$es eq '-') {
Packit 7e8a16
        # ignore fraction part entirely
Packit 7e8a16
        if ($ec >= length($$miv)) {                     # 123.23E-4
Packit 7e8a16
            return '0';
Packit 7e8a16
        }
Packit 7e8a16
        return $sign . substr($$miv, 0, length($$miv) - $ec); # 1234.45E-2 = 12
Packit 7e8a16
    }
Packit 7e8a16
    # xE+y
Packit 7e8a16
    if ($ec >= length($$mfv)) {
Packit 7e8a16
        $ec -= length($$mfv);
Packit 7e8a16
        return $sign.$$miv.$$mfv if $ec == 0;           # 123.45E+2 => 12345
Packit 7e8a16
        return $sign.$$miv.$$mfv.'E'.$ec;               # 123.45e+3 => 12345e1
Packit 7e8a16
    }
Packit 7e8a16
    $mfv = substr($$mfv, 0, $ec);
Packit 7e8a16
    $sign.$$miv.$mfv;                                   # 123.45e+1 => 1234
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub unimport {
Packit 7e8a16
    $^H{bigint} = undef;                                # no longer in effect
Packit 7e8a16
    overload::remove_constant('binary', '', 'float', '', 'integer');
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub in_effect {
Packit 7e8a16
    my $level = shift || 0;
Packit 7e8a16
    my $hinthash = (caller($level))[10];
Packit 7e8a16
    $hinthash->{bigint};
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
#############################################################################
Packit 7e8a16
# the following two routines are for "use bigint qw/hex oct/;":
Packit 7e8a16
Packit 7e8a16
use constant LEXICAL => $] > 5.009004;
Packit 7e8a16
Packit 7e8a16
# Internal function with the same semantics as CORE::hex(). This function is
Packit 7e8a16
# not used directly, but rather by other front-end functions.
Packit 7e8a16
Packit 7e8a16
sub _hex_core {
Packit 7e8a16
    my $str = shift;
Packit 7e8a16
Packit 7e8a16
    # Strip off, clean, and parse as much as we can from the beginning.
Packit 7e8a16
Packit 7e8a16
    my $x;
Packit 7e8a16
    if ($str =~ s/ ^ (0?[xX])? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) {
Packit 7e8a16
        my $chrs = $2;
Packit 7e8a16
        $chrs =~ tr/_//d;
Packit 7e8a16
        $chrs = '0' unless CORE::length $chrs;
Packit 7e8a16
        $x = Math::BigInt -> from_hex($chrs);
Packit 7e8a16
    } else {
Packit 7e8a16
        $x = Math::BigInt -> bzero();
Packit 7e8a16
    }
Packit 7e8a16
Packit 7e8a16
    # Warn about trailing garbage.
Packit 7e8a16
Packit 7e8a16
    if (CORE::length($str)) {
Packit 7e8a16
        require Carp;
Packit 7e8a16
        Carp::carp(sprintf("Illegal hexadecimal digit '%s' ignored",
Packit 7e8a16
                           substr($str, 0, 1)));
Packit 7e8a16
    }
Packit 7e8a16
Packit 7e8a16
    return $x;
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
# Internal function with the same semantics as CORE::oct(). This function is
Packit 7e8a16
# not used directly, but rather by other front-end functions.
Packit 7e8a16
Packit 7e8a16
sub _oct_core {
Packit 7e8a16
    my $str = shift;
Packit 7e8a16
Packit 7e8a16
    $str =~ s/^\s*//;
Packit 7e8a16
Packit 7e8a16
    # Hexadecimal input.
Packit 7e8a16
Packit 7e8a16
    return _hex_core($str) if $str =~ /^0?[xX]/;
Packit 7e8a16
Packit 7e8a16
    my $x;
Packit 7e8a16
Packit 7e8a16
    # Binary input.
Packit 7e8a16
Packit 7e8a16
    if ($str =~ /^0?[bB]/) {
Packit 7e8a16
Packit 7e8a16
        # Strip off, clean, and parse as much as we can from the beginning.
Packit 7e8a16
Packit 7e8a16
        if ($str =~ s/ ^ (0?[bB])? ( [01]* ( _ [01]+ )* ) //x) {
Packit 7e8a16
            my $chrs = $2;
Packit 7e8a16
            $chrs =~ tr/_//d;
Packit 7e8a16
            $chrs = '0' unless CORE::length $chrs;
Packit 7e8a16
            $x = Math::BigInt -> from_bin($chrs);
Packit 7e8a16
        }
Packit 7e8a16
Packit 7e8a16
        # Warn about trailing garbage.
Packit 7e8a16
Packit 7e8a16
        if (CORE::length($str)) {
Packit 7e8a16
            require Carp;
Packit 7e8a16
            Carp::carp(sprintf("Illegal binary digit '%s' ignored",
Packit 7e8a16
                               substr($str, 0, 1)));
Packit 7e8a16
        }
Packit 7e8a16
Packit 7e8a16
        return $x;
Packit 7e8a16
    }
Packit 7e8a16
Packit 7e8a16
    # Octal input. Strip off, clean, and parse as much as we can from the
Packit 7e8a16
    # beginning.
Packit 7e8a16
Packit 7e8a16
    if ($str =~ s/ ^ ( [0-7]* ( _ [0-7]+ )* ) //x) {
Packit 7e8a16
        my $chrs = $1;
Packit 7e8a16
        $chrs =~ tr/_//d;
Packit 7e8a16
        $chrs = '0' unless CORE::length $chrs;
Packit 7e8a16
        $x = Math::BigInt -> from_oct($chrs);
Packit 7e8a16
    }
Packit 7e8a16
Packit 7e8a16
    # Warn about trailing garbage. CORE::oct() only warns about 8 and 9.
Packit 7e8a16
Packit 7e8a16
    if (CORE::length($str)) {
Packit 7e8a16
        my $chr = substr($str, 0, 1);
Packit 7e8a16
        if ($chr eq '8' || $chr eq '9') {
Packit 7e8a16
            require Carp;
Packit 7e8a16
            Carp::carp(sprintf("Illegal octal digit '%s' ignored", $chr));
Packit 7e8a16
        }
Packit 7e8a16
    }
Packit 7e8a16
Packit 7e8a16
    return $x;
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
{
Packit 7e8a16
    my $proto = LEXICAL ? '_' : ';$';
Packit 7e8a16
    eval '
Packit 7e8a16
sub hex(' . $proto . ') {' . <<'.';
Packit 7e8a16
    my $str = @_ ? $_[0] : $_;
Packit 7e8a16
    _hex_core($str);
Packit 7e8a16
}
Packit 7e8a16
.
Packit 7e8a16
Packit 7e8a16
    eval '
Packit 7e8a16
sub oct(' . $proto . ') {' . <<'.';
Packit 7e8a16
    my $str = @_ ? $_[0] : $_;
Packit 7e8a16
    _oct_core($str);
Packit 7e8a16
}
Packit 7e8a16
.
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
#############################################################################
Packit 7e8a16
# the following two routines are for Perl 5.9.4 or later and are lexical
Packit 7e8a16
Packit 7e8a16
my ($prev_oct, $prev_hex, $overridden);
Packit 7e8a16
Packit 7e8a16
if (LEXICAL) { eval <<'.' }
Packit 7e8a16
sub _hex(_) {
Packit 7e8a16
    my $hh = (caller 0)[10];
Packit 7e8a16
    return $prev_hex ? &$prev_hex($_[0]) : CORE::hex($_[0])
Packit 7e8a16
      unless $$hh{bigint}||$$hh{bignum}||$$hh{bigrat};
Packit 7e8a16
    _hex_core($_[0]);
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub _oct(_) {
Packit 7e8a16
    my $hh = (caller 0)[10];
Packit 7e8a16
    return $prev_oct ? &$prev_oct($_[0]) : CORE::oct($_[0])
Packit 7e8a16
      unless $$hh{bigint}||$$hh{bignum}||$$hh{bigrat};
Packit 7e8a16
    _oct_core($_[0]);
Packit 7e8a16
}
Packit 7e8a16
.
Packit 7e8a16
Packit 7e8a16
sub _override {
Packit 7e8a16
    return if $overridden;
Packit 7e8a16
    $prev_oct = *CORE::GLOBAL::oct{CODE};
Packit 7e8a16
    $prev_hex = *CORE::GLOBAL::hex{CODE};
Packit 7e8a16
    no warnings 'redefine';
Packit 7e8a16
    *CORE::GLOBAL::oct = \&_oct;
Packit 7e8a16
    *CORE::GLOBAL::hex = \&_hex;
Packit 7e8a16
    $overridden++;
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub import {
Packit 7e8a16
    my $self = shift;
Packit 7e8a16
Packit 7e8a16
    $^H{bigint} = 1;                            # we are in effect
Packit 7e8a16
Packit 7e8a16
    # for newer Perls always override hex() and oct() with a lexical version:
Packit 7e8a16
    if (LEXICAL) {
Packit 7e8a16
        _override();
Packit 7e8a16
    }
Packit 7e8a16
    # some defaults
Packit 7e8a16
    my $lib = '';
Packit 7e8a16
    my $lib_kind = 'try';
Packit 7e8a16
Packit 7e8a16
    my @import = (':constant');                 # drive it w/ constant
Packit 7e8a16
    my @a = @_;
Packit 7e8a16
    my $l = scalar @_;
Packit 7e8a16
    my $j = 0;
Packit 7e8a16
    my ($ver, $trace);                          # version? trace?
Packit 7e8a16
    my ($a, $p);                                # accuracy, precision
Packit 7e8a16
    for (my $i = 0; $i < $l; $i++, $j++) {
Packit 7e8a16
        if ($_[$i] =~ /^(l|lib|try|only)$/) {
Packit 7e8a16
            # this causes a different low lib to take care...
Packit 7e8a16
            $lib_kind = $1;
Packit 7e8a16
            $lib_kind = 'lib' if $lib_kind eq 'l';
Packit 7e8a16
            $lib = $_[$i + 1] || '';
Packit 7e8a16
            my $s = 2;
Packit 7e8a16
            $s = 1 if @a - $j < 2;  # avoid "can not modify non-existent..."
Packit 7e8a16
            splice @a, $j, $s;
Packit 7e8a16
            $j -= $s;
Packit 7e8a16
            $i++;
Packit 7e8a16
        } elsif ($_[$i] =~ /^(a|accuracy)$/) {
Packit 7e8a16
            $a = $_[$i + 1];
Packit 7e8a16
            my $s = 2;
Packit 7e8a16
            $s = 1 if @a - $j < 2;  # avoid "can not modify non-existent..."
Packit 7e8a16
            splice @a, $j, $s;
Packit 7e8a16
            $j -= $s;
Packit 7e8a16
            $i++;
Packit 7e8a16
        } elsif ($_[$i] =~ /^(p|precision)$/) {
Packit 7e8a16
            $p = $_[$i + 1];
Packit 7e8a16
            my $s = 2;
Packit 7e8a16
            $s = 1 if @a - $j < 2;  # avoid "can not modify non-existent..."
Packit 7e8a16
            splice @a, $j, $s;
Packit 7e8a16
            $j -= $s;
Packit 7e8a16
            $i++;
Packit 7e8a16
        } elsif ($_[$i] =~ /^(v|version)$/) {
Packit 7e8a16
            $ver = 1;
Packit 7e8a16
            splice @a, $j, 1;
Packit 7e8a16
            $j--;
Packit 7e8a16
        } elsif ($_[$i] =~ /^(t|trace)$/) {
Packit 7e8a16
            $trace = 1;
Packit 7e8a16
            splice @a, $j, 1;
Packit 7e8a16
            $j--;
Packit 7e8a16
        } elsif ($_[$i] !~ /^(PI|e|bpi|bexp|hex|oct)\z/) {
Packit 7e8a16
            die ("unknown option $_[$i]");
Packit 7e8a16
        }
Packit 7e8a16
    }
Packit 7e8a16
    my $class;
Packit 7e8a16
    $_lite = 0;                                 # using M::BI::L ?
Packit 7e8a16
    if ($trace) {
Packit 7e8a16
        require Math::BigInt::Trace;
Packit 7e8a16
        $class = 'Math::BigInt::Trace';
Packit 7e8a16
    } else {
Packit 7e8a16
        # see if we can find Math::BigInt::Lite
Packit 7e8a16
        if (!defined $a && !defined $p) {       # rounding won't work to well
Packit 7e8a16
            local @INC = @INC;
Packit 7e8a16
            pop @INC if $INC[-1] eq '.';
Packit 7e8a16
            if (eval { require Math::BigInt::Lite; 1 }) {
Packit 7e8a16
                @import = ();                   # :constant in Lite, not MBI
Packit 7e8a16
                Math::BigInt::Lite->import(':constant');
Packit 7e8a16
                $_lite = 1;                     # signal okay
Packit 7e8a16
            }
Packit 7e8a16
        }
Packit 7e8a16
        require Math::BigInt if $_lite == 0;    # not already loaded?
Packit 7e8a16
        $class = 'Math::BigInt';                # regardless of MBIL or not
Packit 7e8a16
    }
Packit 7e8a16
    push @import, $lib_kind => $lib if $lib ne '';
Packit 7e8a16
    # Math::BigInt::Trace or plain Math::BigInt
Packit 7e8a16
    $class->import(@import);
Packit 7e8a16
Packit 7e8a16
    bigint->accuracy($a)  if defined $a;
Packit 7e8a16
    bigint->precision($p) if defined $p;
Packit 7e8a16
    if ($ver) {
Packit 7e8a16
        print "bigint\t\t\t v$VERSION\n";
Packit 7e8a16
        print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
Packit 7e8a16
        print "Math::BigInt\t\t v$Math::BigInt::VERSION";
Packit 7e8a16
        my $config = Math::BigInt->config();
Packit 7e8a16
        print " lib => $config->{lib} v$config->{lib_version}\n";
Packit 7e8a16
        exit;
Packit 7e8a16
    }
Packit 7e8a16
    # we take care of floating point constants, since BigFloat isn't available
Packit 7e8a16
    # and BigInt doesn't like them:
Packit 7e8a16
    overload::constant float =>
Packit 7e8a16
        sub {
Packit 7e8a16
            Math::BigInt->new(_float_constant(shift));
Packit 7e8a16
        };
Packit 7e8a16
    # Take care of octal/hexadecimal constants
Packit 7e8a16
    overload::constant binary =>
Packit 7e8a16
        sub {
Packit 7e8a16
            _binary_constant(shift);
Packit 7e8a16
        };
Packit 7e8a16
Packit 7e8a16
    # if another big* was already loaded:
Packit 7e8a16
    my ($package) = caller();
Packit 7e8a16
Packit 7e8a16
    no strict 'refs';
Packit 7e8a16
    if (!defined *{"${package}::inf"}) {
Packit 7e8a16
        $self->export_to_level(1, $self, @a);   # export inf and NaN, e and PI
Packit 7e8a16
    }
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
sub inf () { Math::BigInt->binf(); }
Packit 7e8a16
sub NaN () { Math::BigInt->bnan(); }
Packit 7e8a16
Packit 7e8a16
sub PI () { Math::BigInt->new(3); }
Packit 7e8a16
sub e () { Math::BigInt->new(2); }
Packit 7e8a16
sub bpi ($) { Math::BigInt->new(3); }
Packit 7e8a16
sub bexp ($$) {
Packit 7e8a16
    my $x = Math::BigInt->new($_[0]);
Packit 7e8a16
    $x->bexp($_[1]);
Packit 7e8a16
}
Packit 7e8a16
Packit 7e8a16
1;
Packit 7e8a16
Packit 7e8a16
__END__
Packit 7e8a16
Packit 7e8a16
=pod
Packit 7e8a16
Packit 7e8a16
=head1 NAME
Packit 7e8a16
Packit 7e8a16
bigint - Transparent BigInteger support for Perl
Packit 7e8a16
Packit 7e8a16
=head1 SYNOPSIS
Packit 7e8a16
Packit 7e8a16
  use bigint;
Packit 7e8a16
Packit 7e8a16
  $x = 2 + 4.5,"\n";                    # BigInt 6
Packit 7e8a16
  print 2 ** 512,"\n";                  # really is what you think it is
Packit 7e8a16
  print inf + 42,"\n";                  # inf
Packit 7e8a16
  print NaN * 7,"\n";                   # NaN
Packit 7e8a16
  print hex("0x1234567890123490"),"\n"; # Perl v5.10.0 or later
Packit 7e8a16
Packit 7e8a16
  {
Packit 7e8a16
    no bigint;
Packit 7e8a16
    print 2 ** 256,"\n";                # a normal Perl scalar now
Packit 7e8a16
  }
Packit 7e8a16
Packit 7e8a16
  # Import into current package:
Packit 7e8a16
  use bigint qw/hex oct/;
Packit 7e8a16
  print hex("0x1234567890123490"),"\n";
Packit 7e8a16
  print oct("01234567890123490"),"\n";
Packit 7e8a16
Packit 7e8a16
=head1 DESCRIPTION
Packit 7e8a16
Packit 7e8a16
All operators (including basic math operations) except the range operator C<..>
Packit 7e8a16
are overloaded. Integer constants are created as proper BigInts.
Packit 7e8a16
Packit 7e8a16
Floating point constants are truncated to integer. All parts and results of
Packit 7e8a16
expressions are also truncated.
Packit 7e8a16
Packit 7e8a16
Unlike L<integer>, this pragma creates integer constants that are only
Packit 7e8a16
limited in their size by the available memory and CPU time.
Packit 7e8a16
Packit 7e8a16
=head2 use integer vs. use bigint
Packit 7e8a16
Packit 7e8a16
There is one small difference between C<use integer> and C<use bigint>: the
Packit 7e8a16
former will not affect assignments to variables and the return value of
Packit 7e8a16
some functions. C<bigint> truncates these results to integer too:
Packit 7e8a16
Packit 7e8a16
        # perl -Minteger -wle 'print 3.2'
Packit 7e8a16
        3.2
Packit 7e8a16
        # perl -Minteger -wle 'print 3.2 + 0'
Packit 7e8a16
        3
Packit 7e8a16
        # perl -Mbigint -wle 'print 3.2'
Packit 7e8a16
        3
Packit 7e8a16
        # perl -Mbigint -wle 'print 3.2 + 0'
Packit 7e8a16
        3
Packit 7e8a16
Packit 7e8a16
        # perl -Mbigint -wle 'print exp(1) + 0'
Packit 7e8a16
        2
Packit 7e8a16
        # perl -Mbigint -wle 'print exp(1)'
Packit 7e8a16
        2
Packit 7e8a16
        # perl -Minteger -wle 'print exp(1)'
Packit 7e8a16
        2.71828182845905
Packit 7e8a16
        # perl -Minteger -wle 'print exp(1) + 0'
Packit 7e8a16
        2
Packit 7e8a16
Packit 7e8a16
In practice this makes seldom a difference as B<parts and results> of
Packit 7e8a16
expressions will be truncated anyway, but this can, for instance, affect the
Packit 7e8a16
return value of subroutines:
Packit 7e8a16
Packit 7e8a16
    sub three_integer { use integer; return 3.2; }
Packit 7e8a16
    sub three_bigint { use bigint; return 3.2; }
Packit 7e8a16
Packit 7e8a16
    print three_integer(), " ", three_bigint(),"\n";    # prints "3.2 3"
Packit 7e8a16
Packit 7e8a16
=head2 Options
Packit 7e8a16
Packit 7e8a16
bigint recognizes some options that can be passed while loading it via use.
Packit 7e8a16
The options can (currently) be either a single letter form, or the long form.
Packit 7e8a16
The following options exist:
Packit 7e8a16
Packit 7e8a16
=over 2
Packit 7e8a16
Packit 7e8a16
=item a or accuracy
Packit 7e8a16
Packit 7e8a16
This sets the accuracy for all math operations. The argument must be greater
Packit 7e8a16
than or equal to zero. See Math::BigInt's bround() function for details.
Packit 7e8a16
Packit 7e8a16
        perl -Mbigint=a,2 -le 'print 12345+1'
Packit 7e8a16
Packit 7e8a16
Note that setting precision and accuracy at the same time is not possible.
Packit 7e8a16
Packit 7e8a16
=item p or precision
Packit 7e8a16
Packit 7e8a16
This sets the precision for all math operations. The argument can be any
Packit 7e8a16
integer. Negative values mean a fixed number of digits after the dot, and
Packit 7e8a16
are ignored since all operations happen in integer space.
Packit 7e8a16
A positive value rounds to this digit left from the dot. 0 or 1 mean round to
Packit 7e8a16
integer and are ignore like negative values.
Packit 7e8a16
Packit 7e8a16
See Math::BigInt's bfround() function for details.
Packit 7e8a16
Packit 7e8a16
        perl -Mbignum=p,5 -le 'print 123456789+123'
Packit 7e8a16
Packit 7e8a16
Note that setting precision and accuracy at the same time is not possible.
Packit 7e8a16
Packit 7e8a16
=item t or trace
Packit 7e8a16
Packit 7e8a16
This enables a trace mode and is primarily for debugging bigint or
Packit 7e8a16
Math::BigInt.
Packit 7e8a16
Packit 7e8a16
=item hex
Packit 7e8a16
Packit 7e8a16
Override the built-in hex() method with a version that can handle big
Packit 7e8a16
integers. This overrides it by exporting it to the current package. Under
Packit 7e8a16
Perl v5.10.0 and higher, this is not so necessary, as hex() is lexically
Packit 7e8a16
overridden in the current scope whenever the bigint pragma is active.
Packit 7e8a16
Packit 7e8a16
=item oct
Packit 7e8a16
Packit 7e8a16
Override the built-in oct() method with a version that can handle big
Packit 7e8a16
integers. This overrides it by exporting it to the current package. Under
Packit 7e8a16
Perl v5.10.0 and higher, this is not so necessary, as oct() is lexically
Packit 7e8a16
overridden in the current scope whenever the bigint pragma is active.
Packit 7e8a16
Packit 7e8a16
=item l, lib, try or only
Packit 7e8a16
Packit 7e8a16
Load a different math lib, see L<Math Library>.
Packit 7e8a16
Packit 7e8a16
        perl -Mbigint=lib,GMP -e 'print 2 ** 512'
Packit 7e8a16
        perl -Mbigint=try,GMP -e 'print 2 ** 512'
Packit 7e8a16
        perl -Mbigint=only,GMP -e 'print 2 ** 512'
Packit 7e8a16
Packit 7e8a16
Currently there is no way to specify more than one library on the command
Packit 7e8a16
line. This means the following does not work:
Packit 7e8a16
Packit 7e8a16
        perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
Packit 7e8a16
Packit 7e8a16
This will be hopefully fixed soon ;)
Packit 7e8a16
Packit 7e8a16
=item v or version
Packit 7e8a16
Packit 7e8a16
This prints out the name and version of all modules used and then exits.
Packit 7e8a16
Packit 7e8a16
        perl -Mbigint=v
Packit 7e8a16
Packit 7e8a16
=back
Packit 7e8a16
Packit 7e8a16
=head2 Math Library
Packit 7e8a16
Packit 7e8a16
Math with the numbers is done (by default) by a module called
Packit 7e8a16
Math::BigInt::Calc. This is equivalent to saying:
Packit 7e8a16
Packit 7e8a16
        use bigint lib => 'Calc';
Packit 7e8a16
Packit 7e8a16
You can change this by using:
Packit 7e8a16
Packit 7e8a16
        use bignum lib => 'GMP';
Packit 7e8a16
Packit 7e8a16
The following would first try to find Math::BigInt::Foo, then
Packit 7e8a16
Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
Packit 7e8a16
Packit 7e8a16
        use bigint lib => 'Foo,Math::BigInt::Bar';
Packit 7e8a16
Packit 7e8a16
Using C<lib> warns if none of the specified libraries can be found and
Packit 7e8a16
L<Math::BigInt> did fall back to one of the default libraries.
Packit 7e8a16
To suppress this warning, use C<try> instead:
Packit 7e8a16
Packit 7e8a16
        use bignum try => 'GMP';
Packit 7e8a16
Packit 7e8a16
If you want the code to die instead of falling back, use C<only> instead:
Packit 7e8a16
Packit 7e8a16
        use bignum only => 'GMP';
Packit 7e8a16
Packit 7e8a16
Please see respective module documentation for further details.
Packit 7e8a16
Packit 7e8a16
=head2 Internal Format
Packit 7e8a16
Packit 7e8a16
The numbers are stored as objects, and their internals might change at anytime,
Packit 7e8a16
especially between math operations. The objects also might belong to different
Packit 7e8a16
classes, like Math::BigInt, or Math::BigInt::Lite. Mixing them together, even
Packit 7e8a16
with normal scalars is not extraordinary, but normal and expected.
Packit 7e8a16
Packit 7e8a16
You should not depend on the internal format, all accesses must go through
Packit 7e8a16
accessor methods. E.g. looking at $x->{sign} is not a good idea since there
Packit 7e8a16
is no guaranty that the object in question has such a hash key, nor is a hash
Packit 7e8a16
underneath at all.
Packit 7e8a16
Packit 7e8a16
=head2 Sign
Packit 7e8a16
Packit 7e8a16
The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
Packit 7e8a16
You can access it with the sign() method.
Packit 7e8a16
Packit 7e8a16
A sign of 'NaN' is used to represent the result when input arguments are not
Packit 7e8a16
numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
Packit 7e8a16
minus infinity. You will get '+inf' when dividing a positive number by 0, and
Packit 7e8a16
'-inf' when dividing any negative number by 0.
Packit 7e8a16
Packit 7e8a16
=head2 Method calls
Packit 7e8a16
Packit 7e8a16
Since all numbers are now objects, you can use all functions that are part of
Packit 7e8a16
the BigInt API. You can only use the bxxx() notation, and not the fxxx()
Packit 7e8a16
notation, though.
Packit 7e8a16
Packit 7e8a16
But a warning is in order. When using the following to make a copy of a number,
Packit 7e8a16
only a shallow copy will be made.
Packit 7e8a16
Packit 7e8a16
        $x = 9; $y = $x;
Packit 7e8a16
        $x = $y = 7;
Packit 7e8a16
Packit 7e8a16
Using the copy or the original with overloaded math is okay, e.g. the
Packit 7e8a16
following work:
Packit 7e8a16
Packit 7e8a16
        $x = 9; $y = $x;
Packit 7e8a16
        print $x + 1, " ", $y,"\n";     # prints 10 9
Packit 7e8a16
Packit 7e8a16
but calling any method that modifies the number directly will result in
Packit 7e8a16
B<both> the original and the copy being destroyed:
Packit 7e8a16
Packit 7e8a16
        $x = 9; $y = $x;
Packit 7e8a16
        print $x->badd(1), " ", $y,"\n";        # prints 10 10
Packit 7e8a16
Packit 7e8a16
        $x = 9; $y = $x;
Packit 7e8a16
        print $x->binc(1), " ", $y,"\n";        # prints 10 10
Packit 7e8a16
Packit 7e8a16
        $x = 9; $y = $x;
Packit 7e8a16
        print $x->bmul(2), " ", $y,"\n";        # prints 18 18
Packit 7e8a16
Packit 7e8a16
Using methods that do not modify, but test that the contents works:
Packit 7e8a16
Packit 7e8a16
        $x = 9; $y = $x;
Packit 7e8a16
        $z = 9 if $x->is_zero();                # works fine
Packit 7e8a16
Packit 7e8a16
See the documentation about the copy constructor and C<=> in overload, as
Packit 7e8a16
well as the documentation in BigInt for further details.
Packit 7e8a16
Packit 7e8a16
=head2 Methods
Packit 7e8a16
Packit 7e8a16
=over 2
Packit 7e8a16
Packit 7e8a16
=item inf()
Packit 7e8a16
Packit 7e8a16
A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
Packit 7e8a16
handle bareword C<inf> properly.
Packit 7e8a16
Packit 7e8a16
=item NaN()
Packit 7e8a16
Packit 7e8a16
A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
Packit 7e8a16
handle bareword C<NaN> properly.
Packit 7e8a16
Packit 7e8a16
=item e
Packit 7e8a16
Packit 7e8a16
        # perl -Mbigint=e -wle 'print e'
Packit 7e8a16
Packit 7e8a16
Returns Euler's number C<e>, aka exp(1). Note that under bigint, this is
Packit 7e8a16
truncated to an integer, and hence simple '2'.
Packit 7e8a16
Packit 7e8a16
=item PI
Packit 7e8a16
Packit 7e8a16
        # perl -Mbigint=PI -wle 'print PI'
Packit 7e8a16
Packit 7e8a16
Returns PI. Note that under bigint, this is truncated to an integer, and hence
Packit 7e8a16
simple '3'.
Packit 7e8a16
Packit 7e8a16
=item bexp()
Packit 7e8a16
Packit 7e8a16
        bexp($power,$accuracy);
Packit 7e8a16
Packit 7e8a16
Returns Euler's number C<e> raised to the appropriate power, to
Packit 7e8a16
the wanted accuracy.
Packit 7e8a16
Packit 7e8a16
Note that under bigint, the result is truncated to an integer.
Packit 7e8a16
Packit 7e8a16
Example:
Packit 7e8a16
Packit 7e8a16
        # perl -Mbigint=bexp -wle 'print bexp(1,80)'
Packit 7e8a16
Packit 7e8a16
=item bpi()
Packit 7e8a16
Packit 7e8a16
        bpi($accuracy);
Packit 7e8a16
Packit 7e8a16
Returns PI to the wanted accuracy. Note that under bigint, this is truncated
Packit 7e8a16
to an integer, and hence simple '3'.
Packit 7e8a16
Packit 7e8a16
Example:
Packit 7e8a16
Packit 7e8a16
        # perl -Mbigint=bpi -wle 'print bpi(80)'
Packit 7e8a16
Packit 7e8a16
=item upgrade()
Packit 7e8a16
Packit 7e8a16
Return the class that numbers are upgraded to, is in fact returning
Packit 7e8a16
C<$Math::BigInt::upgrade>.
Packit 7e8a16
Packit 7e8a16
=item in_effect()
Packit 7e8a16
Packit 7e8a16
        use bigint;
Packit 7e8a16
Packit 7e8a16
        print "in effect\n" if bigint::in_effect;       # true
Packit 7e8a16
        {
Packit 7e8a16
          no bigint;
Packit 7e8a16
          print "in effect\n" if bigint::in_effect;     # false
Packit 7e8a16
        }
Packit 7e8a16
Packit 7e8a16
Returns true or false if C<bigint> is in effect in the current scope.
Packit 7e8a16
Packit 7e8a16
This method only works on Perl v5.9.4 or later.
Packit 7e8a16
Packit 7e8a16
=back
Packit 7e8a16
Packit 7e8a16
=head1 CAVEATS
Packit 7e8a16
Packit 7e8a16
=over 2
Packit 7e8a16
Packit 7e8a16
=item Operator vs literal overloading
Packit 7e8a16
Packit 7e8a16
C<bigint> works by overloading handling of integer and floating point
Packit 7e8a16
literals, converting them to L<Math::BigInt> objects.
Packit 7e8a16
Packit 7e8a16
This means that arithmetic involving only string values or string
Packit 7e8a16
literals will be performed using Perl's built-in operators.
Packit 7e8a16
Packit 7e8a16
For example:
Packit 7e8a16
Packit 7e8a16
    use bignum;
Packit 7e8a16
    my $x = "900000000000000009";
Packit 7e8a16
    my $y = "900000000000000007";
Packit 7e8a16
    print $x - $y;
Packit 7e8a16
Packit 7e8a16
will output C<0> on default 32-bit builds, since C<bigint> never sees
Packit 7e8a16
the string literals.  To ensure the expression is all treated as
Packit 7e8a16
C<Math::BigInt> objects, use a literal number in the expression:
Packit 7e8a16
Packit 7e8a16
    print +(0+$x) - $y;
Packit 7e8a16
Packit 7e8a16
=item ranges
Packit 7e8a16
Packit 7e8a16
Perl does not allow overloading of ranges, so you can neither safely use
Packit 7e8a16
ranges with bigint endpoints, nor is the iterator variable a bigint.
Packit 7e8a16
Packit 7e8a16
        use 5.010;
Packit 7e8a16
        for my $i (12..13) {
Packit 7e8a16
          for my $j (20..21) {
Packit 7e8a16
            say $i ** $j;  # produces a floating-point number,
Packit 7e8a16
                           # not a big integer
Packit 7e8a16
          }
Packit 7e8a16
        }
Packit 7e8a16
Packit 7e8a16
=item in_effect()
Packit 7e8a16
Packit 7e8a16
This method only works on Perl v5.9.4 or later.
Packit 7e8a16
Packit 7e8a16
=item hex()/oct()
Packit 7e8a16
Packit 7e8a16
C<bigint> overrides these routines with versions that can also handle
Packit 7e8a16
big integer values. Under Perl prior to version v5.9.4, however, this
Packit 7e8a16
will not happen unless you specifically ask for it with the two
Packit 7e8a16
import tags "hex" and "oct" - and then it will be global and cannot be
Packit 7e8a16
disabled inside a scope with "no bigint":
Packit 7e8a16
Packit 7e8a16
        use bigint qw/hex oct/;
Packit 7e8a16
Packit 7e8a16
        print hex("0x1234567890123456");
Packit 7e8a16
        {
Packit 7e8a16
                no bigint;
Packit 7e8a16
                print hex("0x1234567890123456");
Packit 7e8a16
        }
Packit 7e8a16
Packit 7e8a16
The second call to hex() will warn about a non-portable constant.
Packit 7e8a16
Packit 7e8a16
Compare this to:
Packit 7e8a16
Packit 7e8a16
        use bigint;
Packit 7e8a16
Packit 7e8a16
        # will warn only under Perl older than v5.9.4
Packit 7e8a16
        print hex("0x1234567890123456");
Packit 7e8a16
Packit 7e8a16
=back
Packit 7e8a16
Packit 7e8a16
=head1 MODULES USED
Packit 7e8a16
Packit 7e8a16
C<bigint> is just a thin wrapper around various modules of the Math::BigInt
Packit 7e8a16
family. Think of it as the head of the family, who runs the shop, and orders
Packit 7e8a16
the others to do the work.
Packit 7e8a16
Packit 7e8a16
The following modules are currently used by bigint:
Packit 7e8a16
Packit 7e8a16
        Math::BigInt::Lite      (for speed, and only if it is loadable)
Packit 7e8a16
        Math::BigInt
Packit 7e8a16
Packit 7e8a16
=head1 EXAMPLES
Packit 7e8a16
Packit 7e8a16
Some cool command line examples to impress the Python crowd ;) You might want
Packit 7e8a16
to compare them to the results under -Mbignum or -Mbigrat:
Packit 7e8a16
Packit 7e8a16
        perl -Mbigint -le 'print sqrt(33)'
Packit 7e8a16
        perl -Mbigint -le 'print 2*255'
Packit 7e8a16
        perl -Mbigint -le 'print 4.5+2*255'
Packit 7e8a16
        perl -Mbigint -le 'print 3/7 + 5/7 + 8/3'
Packit 7e8a16
        perl -Mbigint -le 'print 123->is_odd()'
Packit 7e8a16
        perl -Mbigint -le 'print log(2)'
Packit 7e8a16
        perl -Mbigint -le 'print 2 ** 0.5'
Packit 7e8a16
        perl -Mbigint=a,65 -le 'print 2 ** 0.2'
Packit 7e8a16
        perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777'
Packit 7e8a16
Packit 7e8a16
=head1 BUGS
Packit 7e8a16
Packit 7e8a16
For information about bugs and how to report them, see the BUGS section in the
Packit 7e8a16
documentation available with the perldoc command.
Packit 7e8a16
Packit 7e8a16
    perldoc bignum
Packit 7e8a16
Packit 7e8a16
=head1 SUPPORT
Packit 7e8a16
Packit 7e8a16
You can find documentation for this module with the perldoc command.
Packit 7e8a16
Packit 7e8a16
    perldoc bigint
Packit 7e8a16
Packit 7e8a16
For more information, see the SUPPORT section in the documentation available
Packit 7e8a16
with the perldoc command.
Packit 7e8a16
Packit 7e8a16
    perldoc bignum
Packit 7e8a16
Packit 7e8a16
=head1 LICENSE
Packit 7e8a16
Packit 7e8a16
This program is free software; you may redistribute it and/or modify it under
Packit 7e8a16
the same terms as Perl itself.
Packit 7e8a16
Packit 7e8a16
=head1 SEE ALSO
Packit 7e8a16
Packit 7e8a16
L<bignum> and L<bigrat>.
Packit 7e8a16
Packit 7e8a16
L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigRat> and L<Math::Big> as well as
Packit 7e8a16
L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
Packit 7e8a16
Packit 7e8a16
=head1 AUTHORS
Packit 7e8a16
Packit 7e8a16
=over 4
Packit 7e8a16
Packit 7e8a16
=item *
Packit 7e8a16
Packit 7e8a16
(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
Packit 7e8a16
Packit 7e8a16
=item *
Packit 7e8a16
Packit 7e8a16
Maintained by Peter John Acklam E<lt>pjacklam@gmail.com<gt>, 2014-.
Packit 7e8a16
Packit 7e8a16
=back
Packit 7e8a16
Packit 7e8a16
=cut