|
Math::BigFloat - Arbitrary size floating point math package
use Math::BigFloat;
my $x = Math::BigFloat->new($str);
my $y = $x->copy();
my $nan = Math::BigFloat->bnan();
my $zero = Math::BigFloat->bzero();
my $inf = Math::BigFloat->binf();
my $inf = Math::BigFloat->binf('-');
my $one = Math::BigFloat->bone();
my $mone = Math::BigFloat->bone('-');
my $pi = Math::BigFloat->bpi(100);
my $cos = Math::BigFloat->new(1)->bcos(100);
my $sin = Math::BigFloat->new(1)->bsin(100);
my $atan = Math::BigFloat->new(1)->batan(100);
my $atan2 = Math::BigFloat->new( 1 )->batan2( 1 ,100);
my $atan2 = Math::BigFloat->new( 1 )->batan2( 8 ,100);
my $atan2 = Math::BigFloat->new( -2 )->batan2( 1 ,100);
$x->is_zero();
$x->is_nan();
$x->is_one();
$x->is_one('-');
$x->is_odd();
$x->is_even();
$x->is_pos();
$x->is_neg();
$x->is_inf(sign);
$x->bcmp($y);
$x->bacmp($y);
$x->sign();
$x->digit($n);
$x->digit(-$n);
$x->bzero();
$x->bnan();
$x->bone();
$x->bone('-');
$x->binf();
$x->binf('-');
$x->bneg();
$x->babs();
$x->bnorm();
$x->bnot();
$x->binc();
$x->bdec();
$x->badd($y);
$x->bsub($y);
$x->bmul($y);
$x->bdiv($y);
$x->bmod($y);
$x->bpow($y);
$x->bmodpow($exp,$mod);
$x->blsft($y, $n);
$x->brsft($y, $n);
$x->blog();
$x->blog($base);
$x->bexp();
$x->band($y);
$x->bior($y);
$x->bxor($y);
$x->bnot();
$x->bsqrt();
$x->broot($y);
$x->bfac();
$x->bround($N);
$x->bfround($N);
$x->bfloor();
$x->bceil();
bgcd(@values);
blcm(@values);
$x->bstr();
$x->bsstr();
$x->as_int();
$x->exponent();
$x->mantissa();
$x->parts();
$x->length();
($l,$f) = $x->length();
$x->precision();
$x->precision($n);
$x->accuracy();
$x->accuracy($n);
Math::BigFloat->precision();
Math::BigFloat->accuracy();
Math::BigFloat->round_mode();
All operators (including basic math operations) are overloaded if you
declare your big floating point numbers as
$i = new Math::BigFloat '12_3.456_789_123_456_789E-2';
Operations with overloaded operators preserve the arguments, which is
exactly what you expect.
Input to these routines are either BigFloat objects, or strings of the
following four forms:
all with optional leading and trailing zeros and/or spaces. Additionally,
numbers are allowed to have an underscore between any two digits.
Empty strings as well as other illegal numbers results in 'NaN'.
bnorm() on a BigFloat object is now effectively a no-op, since the numbers
are always stored in normalized form. On a string, it creates a BigFloat
object.
Output values are BigFloat objects (normalized), except for bstr() and bsstr().
The string output will always have leading and trailing zeros stripped and drop
a plus sign. bstr() will give you always the form with a decimal point,
while bsstr() (s for scientific) gives you the scientific notation.
Input bstr() bsstr()
'-0' '0' '0E1'
' -123 123 123' '-123123123' '-123123123E0'
'00.0123' '0.0123' '123E-4'
'123.45E-2' '1.2345' '12345E-4'
'10E+3' '10000' '1E4'
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.
Actual math is done by using the class defined with with = Class;> (which
defaults to BigInts) to represent the mantissa and exponent.
The sign /^[+-]$/ is stored separately. The string 'NaN' is used to
represent the result when input arguments are not numbers, as well as
the result of dividing by zero.
mantissa() and exponent() return the said parts of the BigFloat
as BigInts such that:
$m = $x->mantissa();
$e = $x->exponent();
$y = $m * ( 10 ** $e );
print "ok\n" if $x == $y;
($m,$e) = $x->parts(); is just a shortcut giving you both of them.
A zero is represented and returned as 0E1, not 0E0 (after Knuth).
Currently the mantissa is reduced as much as possible, favouring higher
exponents over lower ones (e.g. returning 1e7 instead of 10e6 or 10000000e0).
This might change in the future, so do not depend on it.
See also: Rounding.
Math::BigFloat supports both precision (rounding to a certain place before or
after the dot) and accuracy (rounding to a certain number of digits). For a
full documentation, examples and tips on these topics please see the large
section about rounding in the Math::BigInt manpage.
Since things like sqrt(2) or 1 / 3 must presented with a limited
accuracy lest a operation consumes all resources, each operation produces
no more than the requested number of digits.
If there is no gloabl precision or accuracy set, and the operation in
question was not called with a requested precision or accuracy, and the
input $x has no accuracy or precision set, then a fallback parameter will
be used. For historical reasons, it is called div_scale and can be accessed
via:
$d = Math::BigFloat->div_scale();
Math::BigFloat->div_scale($n);
The default value for div_scale is 40.
In case the result of one operation has more digits than specified,
it is rounded. The rounding mode taken is either the default mode, or the one
supplied to the operation after the scale:
$x = Math::BigFloat->new(2);
Math::BigFloat->accuracy(5);
$y = $x->copy()->bdiv(3);
$y = $x->copy()->bdiv(3,6);
$y = $x->copy()->bdiv(3,6,undef,'odd');
Math::BigFloat->round_mode('zero');
$y = $x->copy()->bdiv(3,6);
Note that Math::BigFloat->accuracy() and Math::BigFloat->precision()
set the global variables, and thus any newly created number will be subject
to the global rounding immediately. This means that in the examples above, the
3 as argument to bdiv() will also get an accuracy of 5.
It is less confusing to either calculate the result fully, and afterwards
round it explicitly, or use the additional parameters to the math
functions like so:
use Math::BigFloat;
$x = Math::BigFloat->new(2);
$y = $x->copy()->bdiv(3);
print $y->bround(5),"\n";
or
use Math::BigFloat;
$x = Math::BigFloat->new(2);
$y = $x->copy()->bdiv(3,5);
print "$y\n";
- ffround ( +$scale )
-
Rounds to the $scale'th place left from the '.', counting from the dot.
The first digit is numbered 1.
- ffround ( -$scale )
-
Rounds to the $scale'th place right from the '.', counting from the dot.
- ffround ( 0 )
-
Rounds to an integer.
- fround ( +$scale )
-
Preserves accuracy to $scale digits from the left (aka significant digits)
and pads the rest with zeros. If the number is between 1 and -1, the
significant digits count from the first non-zero after the '.'
- fround ( -$scale ) and fround ( 0 )
-
These are effectively no-ops.
All rounding functions take as a second parameter a rounding mode from one of
the following: 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'.
The default rounding mode is 'even'. By using
Math::BigFloat->round_mode($round_mode); you can get and set the default
mode for subsequent rounding. The usage of $Math::BigFloat::$round_mode is
no longer supported.
The second parameter to the round functions then overrides the default
temporarily.
The as_number() function returns a BigInt from a Math::BigFloat. It uses
'trunc' as rounding mode to make it equivalent to:
$x = 2.5;
$y = int($x) + 2;
You can override this by passing the desired rounding mode as parameter to
as_number():
$x = Math::BigFloat->new(2.5);
$y = $x->as_number('odd');
Math::BigFloat supports all methods that Math::BigInt supports, except it
calculates non-integer results when possible. Please see the Math::BigInt manpage
for a full description of each method. Below are just the most important
differences:
$x->accuracy(5);
CLASS->accuracy(5);
$A = $x->accuracy();
$A = CLASS->accuracy();
Set or get the global or local accuracy, aka how many significant digits the
results have. If you set a global accuracy, then this also applies to new()!
Warning! The accuracy sticks, e.g. once you created a number under the
influence of CLASS->accuracy($A), all results from math operations with
that number will also be rounded.
In most cases, you should probably round the results explicitly using one of
round(), bround() or bfround() or by passing the desired accuracy
to the math operation as additional parameter:
my $x = Math::BigInt->new(30000);
my $y = Math::BigInt->new(7);
print scalar $x->copy()->bdiv($y, 2);
print scalar $x->copy()->bdiv($y)->bround(2);
$x->precision(-2);
$x->precision(2);
CLASS->precision(5);
CLASS->precision(-5);
$P = CLASS->precision();
$P = $x->precision();
Note: You probably want to use accuracy() instead. With the accuracy manpage you
set the number of digits each result should have, with precision you
set the place where to round!
$x->bexp($accuracy);
Calculates the expression e ** $x where e is Euler's number.
This method was added in v1.82 of Math::BigInt (April 2007).
$x->bnok($y);
|