Math::BigInt - Arbitrary size integer math package
use Math::BigInt; # is default '+')  $x to 0 $x->bnan(); # set $x->round($A,$P,$round_mode); # round to accuracy or precision using mode $r $x->bround($N); # accuracy: preserve $N digits $x->bfround($N); # round to $Nth digit, no-op for BigInts # The following do not modify their arguments in BigInt, but do in BigFloat: $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: bgcd(@values); # greatest common divisor blcm(@values); # lowest common multiplicator $x->bstr(); # normalized string $x->bsstr(); # normalized string in scientific notation $x->length(); # return number of digits in number ($x,$f) = $x->length(); # length of number and length of fraction part $x->exponent(); # return exponent as BigInt $x->mantissa(); # return mantissa as BigInt $x->parts(); # return (mantissa,exponent) as BigInt $x->copy(); # make a true copy of $x (unlike $y = $x;) $x->as_number(); # return as BigInt (in BigInt: same as copy())
All operators (inlcuding basic math operations) are overloaded if you declare your big integers as
$i = new Math::BigInt '123_456_789_123_456_789';
Operations with overloaded operators preserve the arguments which is exactly what you expect.
Big integer values are strings of the form
/^[+-]\d+$/ with leading zeros suppressed.
'-0' canonical value '-0', normalized '0' ' -123_123_123' canonical value '-123123123' '1_23_456_7890' canonical value '1234567890'
Input values to these routines may be either Math::BigInt objects or strings of the form
/^\s*[+-]?[\d]+\.?[\d]*E?[+-]?[\d]*$/.
You can include one underscore between any two digits.
This means integer values like 1.01E2 or even 1000E-2 are also accepted. Non integer values result in NaN.
Math::BigInt::new() defaults to 0, while Math::BigInt::new('') results in 'NaN'.
bnorm() on a BigInt object is now effectively a no-op, since the numbers are always stored in normalized form. On a string, it creates a BigInt object.
Output values are BigInt objects (normalized), except for bstr(), which returns a string in normalized form. Some routines (
is_odd(),
is_even(),
is_zero(),
is_one(),
is_nan()) return true or false, while others (
bcmp(),
bacmp()) return either undef, <0, 0 or >0 and are suited for sort.
Since version v1.33, Math::BigInt and Math::BigFloat have full support for accuracy and precision based rounding, both automatically after every operation as well as manually. other people or documentation).
During the rest of this document, the shortcuts A (for accuracy), P (for precision), F (fallback) and R (rounding mode) will be used.
A fixed number of digits before (positive) or after (negative) precisions, because 1200 can have p = 0, 1 or 2 (depending on what the inital value was). It could also have p < 0, when the digits after the decimal point are zero.
!The string output of such a number should be padded with zeros: ! ! Initial value0000 has 8 and 0.000123 has 3.
When both A and P are undefined, this is used as a fallback accuracy.
When rounding a number, different 'styles' or 'kinds' of rounding are possible. (Note that random rounding, as in Math::Round, is not implemented.)
truncation invariably removes all digits following the rounding place, replacing them with zeros. Thus, 987.65 rounded to tens (P=1) becomes 980, and rounded to the fourth sigdig becomes 987.6 (A=4). 123.456 rounded to the second place after the decimal point (P=-2) becomes 123.46.:
rounds the digit at the rounding place to 0, 2, 4, 6, or 8 if it is not already. E.g., when rounding to the first sigdig, 0.45 becomes 0.4, -0.55 becomes -0.6, but 0.4501 becomes 0.5.
rounds the digit at the rounding place to 1, 3, 5, 7, or 9 if it is not already. E.g., when rounding to the first sigdig, 0.45 becomes 0.5, -0.55 becomes -0.5, but 0.5501 becomes 0.6.
round to plus infinity, i.e. always round up. E.g., when rounding to the first sigdig, 0.45 becomes 0.5, -0.55 becomes -0.5, and 0.4501 also becomes 0.5.
round to minus infinity, i.e. always round down. E.g., when rounding to the first sigdig, 0.45 becomes 0.4, -0.55 becomes -0.6, but 0.4501 becomes 0.5.
round to zero, i.e. positive numbers down, negative ones up. E.g., when rounding to the first sigdig, 0.45 becomes 0.4, -0.55 becomes -0.5, but 0.4501 becomes 0.5.ups) and actually gets 2 for '+100' and 4 for '+101'. Oups reminder, take $Math::SomeClass::accuracy * use $x->accuracy() for the local setting of $x. * to find out the current global P, take $Math::SomeClass::precision * use $x->precision() for the local setting
!* When you create a number, there should be a way to define its A & P * When a number without specific A or P is created, but the globals are defined, these should be used to round the number immediately and also stored locally with the number. Thus changing the global defaults later on will not change the A or P of previously created numbers (i.e., A and P of $x will be what was in effect when $x was created)
* If A or P are enabled/defined, they are used to round the result of each operation according to the rules below * Negative P is ignored in Math::BigInt, since BigInts never have digits after the decimal point !* Math::BigFloat uses Math::BigInts internally, but setting A or P inside ! Math::BigInt as globals should not tamper with the parts of a BigFloat. ! Thus a flag is used to mark all Math::BigFloat numbers as 'never round'
* It only makes sense that a number has only one of A or P at a time. Since you can set/get both A and P, there is a rule that will practically enforce only A or P to be in effect at a time, even if both are set. This is called precedence. !* If two objects are involved in an operation, and one of them has A in ! effect, and the other P, this should result in a warning or an error, ! probably in NaN. * A takes precendence over P (Hint: A comes before P). If A is defined, it is used, otherwise P is used. 1 more digit than required (determined by A, P or F), and, if F is not used, round the result (this will still fail in the case of a result like 0.12345000000001 with A or P of 5, but this cannot be helped - or can it?) * Thus you can have the math done by on Math::Big* class in three modes: + place by one for binary operations like add).: smaller one is taken) + global A + global P + global F * fsqrt() will hand its arguments to fdiv(), as it used to, only now for two arguments (A and P) instead of one
* You can set A and P locally by using $x->accuracy() and $x->precision() and thus force different A and P for different objects/numbers. * Setting A or P this way immediately rounds $x to the new value.
* and get the global R by using Math::SomeClass->round_mode() or by setting $Math::SomeClass::rnd_mode * after each operation, $result->round() is called, and the result may eventually be rounded (that is, if A or P were set either locally, globally or as parameter to the operation) * to manually round a number, call $x->round($A,$P,$rnd
The actual numbers are stored as unsigned big integers, and math with them is done (by default) by a module called Math::BigInt::Calc. This is equivalent to:
use Math::BigInt lib => 'calc';
You can change this by using:
use Math::BigInt lib => 'BitVect';
('Math::BitInt::BitVect' works, too.)
Calc.pm uses as internal format an array of elements of base 100000 digits with the least significant digit first, BitVect.pm uses a bit vector of base 2, most significant bit first.
The sign
/^[+-]$/ is stored separately. The string 'NaN' is used to represent the result when input arguments are not numbers. '+inf' and '-inf' represent infinity.
You should neither care about nor depend on the internal representation; it might change without notice. Use only method calls like
$x->sign(); instead of relying on the internal hash keys like in
$x->{sign};. will be always 0, except for NaN where it will be NaN and for $x == 0, then it will be 1 (to be compatible with Math::BigFloat's internal representation of a zero as
0E1).
$m will always be a copy of the original number. The relation between $e and $m might change in the future, but will always be equivalent in a numerical sense, e.g. $m might get minimized.
use Math::BigInt qw(bstr bint); $x = bstr("1234") # string "1234" $x = "$x"; # same as bstr() $x = bneg("1234") # Bigint "-1234"  = new Math::BigInt; # BigInt "0" $x--; # BigInt "-1" $x = Math::BigInt->badd(4,5) # BigInt "9"  $Math::BigFloat::precision = 2; # P important print $x->copy()->bnorm(),"\n"; # 123.46 print $x->copy()->fround(),"\n"; # 123.46
After
use Math::BigInt ':constant' all the integer decimal constants in the given scope are converted to
Math::BigInt. This conversion happens at compile time.. This is currently not implemented.
The new version of this module is slower on new(), bstr() and numify(). Some operations may be slower for small numbers, but are significantly faster for big numbers. Other operations are now constant (O(1), like bneg(), babs() etc), instead of O(N) and thus nearly always take much less time.
For more benchmark results see
You can use an alternative library to drive Math::BigInt via:
use Math::BigInt lib => 'Module';
The default is called Math::BigInt::Calc and is a pure-perl base 100,000 math package that consists of the standard routine present in earlier versions of Math::BigInt.
There are also Math::BigInt::Scalar (primarily for testing) and Math::BigInt::BitVect; these and others can be found via:
use Math::BigInt lib => 'BitVect'; my $x = Math::BigInt->new(2); print $x ** (1024*1024);
Under Perl prior to 5.6.0 having an
use Math::BigInt ':constant'; and
eval() in your code will crash with "Out of memory". This is probably an overload/exporter bug. You can workaround by not having
eval() and ':constant' at the same time or upgrade your Perl.
Some things might not work as you expect them. Below is documented what is known to be troublesome:
Both stringify and bstr() now drop the leading '+'. The old code would return '+3', the new returns '3'. This is to be consistent with Perl and to make cmp (especially with overloading) to work as you expect. It also solves problems with Test.pm, it's ok() uses 'eq' internally.
Mark doing eq:
use Test; BEGIN { plan tests => 3 } use Math::BigInt; $x = Math::BigInt->new('1e56'); $y = 1e56; ok ($x,$y); # will fail ok ($x->bsstr(),$y); # okay $y = Math::BigInt->new($y); ok ($x,$y); # okay
int() will return (at least for Perl v5.7.1 and up) another BigInt, not a Perl scal.
The following will probably not do what you expect:
print $c->bdiv(10000),"\n";
It prints both quotient and reminder for overload.pm regarding
=.
bpow() (and the rounding functions) now modifies the first argument and return.
The following:
 will be gone. Stay tuned...
In Perl you will get a floating point value if you do one of the following:
, this one's operation.
bsqrt() works only good if the result is an big integer, e.g. the square root of 144 is 12, but from 12 the square root is 3, regardless of rounding mode.
This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.
Math::BigFloat and Math::Big.
Original code by Mark Biggar, overloaded interface by Ilya Zakharevich. Completely rewritten by Tels in late 2000, 2001.