# _a : accuracy
# _p : precision
-$VERSION = '1.49';
+$VERSION = '1.50';
require 5.005;
require Exporter;
$downgrade = undef;
# the package we are using for our private parts, defaults to:
# Math::BigInt->config()->{lib}
-my $MBI = 'Math::BigInt::Calc';
+my $MBI = 'Math::BigInt::FastCalc';
# are NaNs ok? (otherwise it dies when encountering an NaN) set w/ config()
$_trap_nan = 0;
# else: got a string
# handle '+inf', '-inf' first
- if ($wanted =~ /^[+-]?inf$/)
+ if ($wanted =~ /^[+-]?inf\z/)
{
return $downgrade->new($wanted) if $downgrade;
- $self->{_e} = $MBI->_zero();
- $self->{_es} = '+';
- $self->{_m} = $MBI->_zero();
- $self->{sign} = $wanted;
- $self->{sign} = '+inf' if $self->{sign} eq 'inf';
- return $self->bnorm();
+ $self->{sign} = $wanted; # set a default sign for bstr()
+ return $self->binf($wanted);
}
# shortcut for simple forms like '12' that neither have trailing nor leading
my $xsign = $x->{sign};
$y->{sign} =~ tr/+-/-+/;
- my $y_not_one = !$y->is_one(); # cache this result
+
+ # check that $y is not 1 nor -1 and cache the result:
+ my $y_not_one = !($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m}));
+
if ($xsign ne $x->{sign})
{
# special case of $x /= $x results in 1
- $x->bone();
+ $x->bone(); # "fixes" also sign of $y, since $x is $y
}
else
{
return $x->bnan() if $x->is_zero();
return $x;
}
- return $x->bzero() if $y->is_one() || $x->is_zero();
+
+ return $x->bzero() if $x->is_zero() ||
+ # check that $y == -1 or +1:
+ ($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m}));
my $cmp = $x->bacmp($y); # equal or $x < $y?
return $x->bzero($a,$p) if $cmp == 0; # $x == $y => result 0
See also: L<Rounding|Rounding>.
-Math::BigFloat supports both precision and accuracy. For a full documentation,
-examples and tips on these topics please see the large section in
-L<Math::BigInt>.
+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 L<Math::BigInt>.
-Since things like sqrt(2) or 1/3 must presented with a limited precision lest
-a operation consumes all resources, each operation produces no more than
-the requested number of digits.
+Since things like C<sqrt(2)> or C<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.
-Please refer to BigInt's documentation for the precedence rules of which
-accuracy/precision setting will be used.
-
-If there is no gloabl precision set, B<and> the operation inquestion was not
-called with a requested precision or accuracy, B<and> the input $x has no
-accuracy or precision set, then a fallback parameter will be used. For
-historical reasons, it is called C<div_scale> and can be accessed via:
+If there is no gloabl precision or accuracy set, B<and> the operation in
+question was not called with a requested precision or accuracy, B<and> the
+input $x has no accuracy or precision set, then a fallback parameter will
+be used. For historical reasons, it is called C<div_scale> and can be accessed
+via:
$d = Math::BigFloat->div_scale(); # query
Math::BigFloat->div_scale($n); # set to $n digits
-The default value is 40 digits.
+The default value for C<div_scale> is 40.
-In case the result of one operation has more precision than specified,
+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 I<scale>:
Note that C<< Math::BigFloat->accuracy() >> and C<< Math::BigFloat->precision() >>
set the global variables, and thus B<any> newly created number will be subject
-to the global rounding. This means that in the examples above, the C<3>
-as argument to C<bdiv()> will also get an accuracy of B<5>.
+to the global rounding B<immidiately>. This means that in the examples above, the
+C<3> as argument to C<bdiv()> will also get an accuracy of B<5>.
It is less confusing to either calculate the result fully, and afterwards
round it explicitely, or use the additional parameters to the math
$x = Math::BigFloat->new(2.5);
$y = $x->as_number('odd'); # $y = 3
-=head1 EXAMPLES
-
- # not ready yet
+=head1 METHODS
+
+=head2 accuracy
+
+ $x->accuracy(5); # local for $x
+ CLASS->accuracy(5); # global for all members of CLASS
+ # Note: This also applies to new()!
+
+ $A = $x->accuracy(); # read out accuracy that affects $x
+ $A = CLASS->accuracy(); # read out global 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 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.
+
+In most cases, you should probably round the results explicitely using one of
+L<round()>, L<bround()> or L<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 4300
+ print scalar $x->copy()->bdiv($y)->bround(2); # print 4300
+
+=head2 precision()
+
+ $x->precision(-2); # local for $x, round at the second digit right of the dot
+ $x->precision(2); # ditto, round at the second digit left of the dot
+
+ CLASS->precision(5); # Global for all members of CLASS
+ # This also applies to new()!
+ CLASS->precision(-5); # ditto
+
+ $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
+set the number of digits each result should have, with L<precision> you
+set the place where to round!
=head1 Autocreating constants
print $x->bpow($i),"\n"; # ditto
print $x ** $i,"\n"; # leave $x alone
+=item precision() vs. accuracy()
+
+A common pitfall is to use L<precision()> when you want to round a result to
+a certain number of digits:
+
+ use Math::BigFloat;
+
+ Math::BigFloat->precision(4); # does not do what you think it does
+ my $x = Math::BigFloat->new(12345); # rounds $x to "12000"!
+ print "$x\n"; # print "12000"
+ my $y = Math::BigFloat->new(3); # rounds $y to "0"!
+ print "$y\n"; # print "0"
+ $z = $x / $y; # 12000 / 0 => NaN!
+ print "$z\n";
+ print $z->precision(),"\n"; # 4
+
+Replacing L<precision> with L<accuracy> is probably not what you want, either:
+
+ use Math::BigFloat;
+
+ Math::BigFloat->accuracy(4); # enables global rounding:
+ my $x = Math::BigFloat->new(123456); # rounded immidiately to "12350"
+ print "$x\n"; # print "123500"
+ my $y = Math::BigFloat->new(3); # rounded to "3
+ print "$y\n"; # print "3"
+ print $z = $x->copy()->bdiv($y),"\n"; # 41170
+ print $z->accuracy(),"\n"; # 4
+
+What you want to use instead is:
+
+ use Math::BigFloat;
+
+ my $x = Math::BigFloat->new(123456); # no rounding
+ print "$x\n"; # print "123456"
+ my $y = Math::BigFloat->new(3); # no rounding
+ print "$y\n"; # print "3"
+ print $z = $x->copy()->bdiv($y,4),"\n"; # 41150
+ print $z->accuracy(),"\n"; # undef
+
+In addition to computing what you expected, the last example also does B<not>
+"taint" the result with an accuracy or precision setting, which would
+influence any further operation.
+
=back
=head1 SEE ALSO
my $class = "Math::BigInt";
require 5.005;
-$VERSION = '1.75';
+$VERSION = '1.76';
-@ISA = qw( Exporter );
-@EXPORT_OK = qw( objectify bgcd blcm);
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(objectify bgcd blcm);
# _trap_inf and _trap_nan are internal and should never be accessed from the
# outside
$_trap_inf = 0; # are infs ok? set w/ config()
my $nan = 'NaN'; # constants for easier life
-my $CALC = 'Math::BigInt::Calc'; # module to do the low level math
- # default is Calc.pm
+my $CALC = 'Math::BigInt::FastCalc'; # module to do the low level math
+ # default is FastCalc.pm
my $IMPORT = 0; # was import() called yet?
# used to make require work
my %WARN; # warn only once for low-level libs
}
# handle '+inf', '-inf' first
- if ($wanted =~ /^[+-]?inf$/)
+ if ($wanted =~ /^[+-]?inf\z/)
{
- $self->{value} = $CALC->_zero();
- $self->{sign} = $wanted; $self->{sign} = '+inf' if $self->{sign} eq 'inf';
- return $self;
+ $self->{sign} = $wanted; # set a default sign for bstr()
+ return $self->binf($wanted);
}
# split str in m mantissa, e exponent, i integer, f fraction, v value, s sign
my ($mis,$miv,$mfv,$es,$ev) = _split($wanted);
if (${"${class}::_trap_inf"})
{
require Carp;
- Carp::croak ("Tried to set $self to +-inf in $class\::binfn()");
+ Carp::croak ("Tried to set $self to +-inf in $class\::binf()");
}
$self->import() if $IMPORT == 0; # make require work
return if $self->modify('binf');
{
$_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
}
- push @c,'Calc'; # if all fail, try this
+ push @c, 'FastCalc', 'Calc'; # if all fail, try these
$CALC = ''; # signal error
foreach my $lib (@c)
{
1;
__END__
+=pod
+
=head1 NAME
-Math::BigInt - Arbitrary size integer math package
+Math::BigInt - Arbitrary size integer/float math package
=head1 SYNOPSIS
$x->accuracy(5); # local for $x
CLASS->accuracy(5); # global for all members of CLASS
- $A = $x->accuracy(); # read out
- $A = CLASS->accuracy(); # read out
+ # Note: This also applies to new()!
+
+ $A = $x->accuracy(); # read out accuracy that affects $x
+ $A = CLASS->accuracy(); # read out global accuracy
Set or get the global or local accuracy, aka how many significant digits the
-results have.
+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.
+
+In most cases, you should probably round the results explicitely using one of
+L<round()>, L<bround()> or L<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 4300
+ print scalar $x->copy()->bdiv($y)->bround(2); # print 4300
Please see the section about L<ACCURACY AND PRECISION> for further details.
$y = Math::BigInt->new(1234567); # unrounded
print Math::BigInt->accuracy(4),"\n"; # set 4, print 4
- $x = Math::BigInt->new(123456); # will be automatically rounded
+ $x = Math::BigInt->new(123456); # $x will be automatically rounded!
print "$x $y\n"; # '123500 1234567'
print $x->accuracy(),"\n"; # will be 4
print $y->accuracy(),"\n"; # also 4, since global is 4
=head2 precision
- $x->precision(-2); # local for $x, round right of the dot
- $x->precision(2); # ditto, but round left of the dot
- CLASS->accuracy(5); # global for all members of CLASS
- CLASS->precision(-5); # ditto
- $P = CLASS->precision(); # read out
- $P = $x->precision(); # read out
+ $x->precision(-2); # local for $x, round at the second digit right of the dot
+ $x->precision(2); # ditto, round at the second digit left of the dot
+
+ CLASS->precision(5); # Global for all members of CLASS
+ # This also applies to new()!
+ CLASS->precision(-5); # ditto
+
+ $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
+set the number of digits each result should have, with L<precision> you
+set the place where to round!
-Set or get the global or local precision, aka how many digits the result has
-after the dot (or where to round it when passing a positive number). In
-Math::BigInt, passing a negative number precision has no effect since no
-numbers have digits after the dot.
+C<precision()> sets or gets the global or local precision, aka at which digit
+before or after the dot to round all results. A set global precision also
+applies to all newly created numbers!
+
+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.
-Value must be greater than zero. Pass an undef value to disable it:
+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
-value represents the accuracy that will be in effect for $x:
+value represents the prevision that will be in effect for $x:
$y = Math::BigInt->new(1234567); # unrounded
print Math::BigInt->precision(4),"\n"; # set 4, print 4
$x = Math::BigInt->new(123456); # will be automatically rounded
+ print $x; # print "120000"!
-Note: Works also for subclasses like Math::BigFloat. Each class has it's own
-globals separated from Math::BigInt, but it is possible to subclass
+Note: Works also for subclasses like L<Math::BigFloat>. Each class has its
+own globals separated from Math::BigInt, but it is possible to subclass
Math::BigInt and make the globals of the subclass aliases to the ones from
Math::BigInt.
use vars qw/$VERSION/;
-$VERSION = '0.45';
+$VERSION = '0.46';
# Package to store unsigned big integers in decimal and do math with them
sub api_version () { 1; }
# constants for easier life
-my ($MBASE,$BASE,$RBASE,$BASE_LEN,$MAX_VAL,$BASE_LEN_SMALL);
+my ($BASE,$BASE_LEN,$MBASE,$RBASE,$MAX_VAL,$BASE_LEN_SMALL);
my ($AND_BITS,$XOR_BITS,$OR_BITS);
my ($AND_MASK,$XOR_MASK,$OR_MASK);
}
}
return $BASE_LEN unless wantarray;
- return ($BASE_LEN, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN_SMALL, $MAX_VAL);
+ return ($BASE_LEN, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN_SMALL, $MAX_VAL, $BASE);
}
sub _new
plan tests => 26;
}
-use Math::BigFloat;
+use Math::BigFloat lib => 'Calc';
#############################################################################
# add
}
print "# INC = @INC\n";
- plan tests => 1992;
+ plan tests => 2012;
}
use Math::BigFloat lib => 'BareCalc';
0:1:0,0
9:4:2.25,1
9:5:1.8,4
+# bug in v1.74 with bdiv in list context, when $y is 1 or -1
+2.1:-1:-2.1,0
+2.1:1:2.1,0
+-2.1:-1:2.1,0
+-2.1:1:-2.1,0
&fdiv
$div_scale = 40; $round_mode = 'even'
abc:abc:NaN
1230:2.5:0
123.4:2.5:0.9
123e1:25:5
+# 1 or -1 always gives remainder zero (bug up to v1.74)
+-2.1:1:0
+2.1:1:0
+-2.1:-1:0
+2.1:-1:0
+-3:1:0
+3:1:0
+-3:-1:0
+3:-1:0
&ffac
Nanfac:NaN
-1:NaN
}
print "# INC = @INC\n";
- plan tests => 1992
+ plan tests => 2012
+ 2; # own tests
}
-use Math::BigInt;
+use Math::BigInt lib => 'Calc';
use Math::BigFloat;
use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
plan tests => 3014;
}
-use Math::BigInt;
+use Math::BigInt lib => 'Calc';
use vars qw ($scale $class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
$class = "Math::BigInt";
package main;
-use Math::BigInt;
+use Math::BigInt lib => 'Calc';
use Math::BigFloat;
my ($x,$y,$z,$u);
-my $version = '1.61'; # adjust manually to match latest release
+my $version = '1.76'; # adjust manually to match latest release
###############################################################################
# check whether op's accept normal strings, even when inherited by subclasses
$try = "use $class ($version,'lib','foo, bar , ');";
$try .= "$class\->config()->{lib};";
$ans = eval $try;
-ok ( $ans, "Math::BigInt::Calc");
+ok ( $ans =~ /^Math::BigInt::(Fast)?Calc\z/, 1);
# test whether constant works or not, also test for qw($version)
# bgcd() is present in subclass, too
# all done
-###############################################################################
-# Perl 5.005 does not like ok ($x,undef)
-
-sub ok_undef
- {
- my $x = shift;
-
- ok (1,1) and return if !defined $x;
- ok ($x,'undef');
- }
-
__END__
&is_zero
1:0
# test whether Math::BigInt->config() and Math::BigFloat->config() works
-use Math::BigInt;
+use Math::BigInt lib => 'Calc';
use Math::BigFloat;
my $mbi = 'Math::BigInt'; my $mbf = 'Math::BigFloat';
##############################################################################
# test setting illegal keys (should croak)
-my $never_reached = 0;
+$@ = ""; my $never_reached = 0;
eval ("$mbi\->config( 'some_garbage' => 1 ); $never_reached = 1;");
ok ($never_reached,0);
-$never_reached = 0;
+$@ = ""; $never_reached = 0;
eval ("$mbf\->config( 'some_garbage' => 1 ); $never_reached = 1;");
ok ($never_reached,0);
# this does not work. Why?
-#ok (@!, "Illegal keys 'some_garbage' passed to Math::BigInt->config() at ./config.t line 104");
+#ok ($@ eq "Illegal keys 'some_garbage' passed to Math::BigInt->config() at ./config.t line 104", 1);
# all tests done
# check that simple requiring BigFloat and then bzero() works
use strict;
-use Test;
+use Test::More;
BEGIN
{
plan tests => 1;
}
-require Math::BigFloat; my $x = Math::BigFloat->bzero(); ok ($x,0);
+require Math::BigFloat;
+my $x = Math::BigFloat->bzero(); $x++;
+is ($x,1, '$x is 1');
# all tests done
# check that requiring BigFloat and then calling import() works
use strict;
-use Test;
+use Test::More;
BEGIN
{
}
# normal require that calls import automatically (we thus have MBI afterwards)
-require Math::BigFloat; my $x = Math::BigFloat->new(1); ++$x; ok ($x,2);
+require Math::BigFloat;
+my $x = Math::BigFloat->new(1); ++$x;
+is ($x,2, '$x is 2');
-ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Calc' );
+like (Math::BigFloat->config()->{with}, qr/^Math::BigInt::(Fast)?Calc\z/, 'with ignored' );
# now override
Math::BigFloat->import ( with => 'Math::BigInt::Subclass' );
-# thw with argument is ignored
-ok (Math::BigFloat->config()->{with}, 'Math::BigInt::Calc' );
+# the "with" argument is ignored
+like (Math::BigFloat->config()->{with}, qr/^Math::BigInt::(Fast)?Calc\z/, 'with ignored' );
# all tests done
}
print "# INC = @INC\n";
- plan tests => 1992
+ plan tests => 2012
+ 6; # + our own tests
}
use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
$class = "Math::BigFloat::Subclass";
-$CL = "Math::BigInt::Calc";
+$CL = Math::BigFloat->config()->{lib}; # "Math::BigInt::Calc"; or FastCalc
require 'bigfltpm.inc'; # perform same tests as bigfltpm
# test that config ( trap_nan => 1, trap_inf => 1) really works/dies
use strict;
-use Test;
+use Test::More;
BEGIN
{
$| = 1;
chdir 't' if -d 't';
unshift @INC, '../lib'; # for running manually
- plan tests => 35;
+ plan tests => 43;
}
use Math::BigInt;
foreach my $class ($mbi, $mbf)
{
# can do and defaults are okay?
- ok ($class->can('config'));
- ok ($class->config()->{trap_nan}, 0);
- ok ($class->config()->{trap_inf}, 0);
+ ok ($class->can('config'), 'can config()');
+ is ($class->config()->{trap_nan}, 0, 'trap_nan defaults to 0');
+ is ($class->config()->{trap_inf}, 0, 'trap_inf defaults to 0');
# can set?
- $cfg = $class->config( trap_nan => 1 ); ok ($cfg->{trap_nan},1);
+ $cfg = $class->config( trap_nan => 1 );
+ is ($cfg->{trap_nan},1, 'trap_nan now true');
# also test that new() still works normally
eval ("\$x = \$class->new('42'); \$x->bnan();");
- ok ($@ =~/^Tried to set/, 1);
- ok ($x,42); # after new() never modified
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,42,'$x after new() never modified');
# can reset?
- $cfg = $class->config( trap_nan => 0 ); ok ($cfg->{trap_nan},0);
+ $cfg = $class->config( trap_nan => 0 );
+ is ($cfg->{trap_nan}, 0, 'trap_nan disabled');
# can set?
- $cfg = $class->config( trap_inf => 1 ); ok ($cfg->{trap_inf},1);
+ $cfg = $class->config( trap_inf => 1 );
+ is ($cfg->{trap_inf}, 1, 'trap_inf enabled');
+
eval ("\$x = \$class->new('4711'); \$x->binf();");
- ok ($@ =~/^Tried to set/, 1);
- ok ($x,4711); # after new() never modified
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,4711,'$x after new() never modified');
+
+ eval ("\$x = \$class->new('inf');");
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,4711,'$x after new() never modified');
+
+ eval ("\$x = \$class->new('-inf');");
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,4711,'$x after new() never modified');
# +$x/0 => +inf
eval ("\$x = \$class->new('4711'); \$x->bdiv(0);");
- ok ($@ =~/^Tried to set/, 1);
- ok ($x,4711); # after new() never modified
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,4711,'$x after new() never modified');
# -$x/0 => -inf
eval ("\$x = \$class->new('-0815'); \$x->bdiv(0);");
- ok ($@ =~/^Tried to set/, 1);
- ok ($x,-815); # after new() never modified
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,'-815', '$x after new not modified');
$cfg = $class->config( trap_nan => 1 );
# 0/0 => NaN
eval ("\$x = \$class->new('0'); \$x->bdiv(0);");
- ok ($@ =~/^Tried to set/, 1);
- ok ($x,0); # after new() never modified
+ like ($@, qr/^Tried to set/, 'died');
+ is ($x,'0', '$x after new not modified');
}
##############################################################################
$x = Math::BigInt->new(2);
eval ("\$x = \$mbi->new('0.1');");
-ok ($x,2); # never modified since it dies
+is ($x,2,'never modified since it dies');
eval ("\$x = \$mbi->new('0a.1');");
-ok ($x,2); # never modified since it dies
-
+is ($x,2,'never modified since it dies');
##############################################################################
# BigFloat
$x = Math::BigFloat->new(2);
eval ("\$x = \$mbf->new('0.1a');");
-ok ($x,2); # never modified since it dies
+is ($x,2,'never modified since it dies');
# all tests done
}
print "# INC = @INC\n";
- plan tests => 1992
+ plan tests => 2012
+ 1;
}
-use Math::BigFloat with => 'Math::BigInt::Subclass';
+use Math::BigFloat with => 'Math::BigInt::Subclass', lib => 'Calc';
use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
$class = "Math::BigFloat";
require 5.005_03;
use strict;
-require Exporter;
use Math::BigFloat;
use vars qw($VERSION @ISA $upgrade $downgrade
$accuracy $precision $round_mode $div_scale $_trap_nan $_trap_inf);
-@ISA = qw(Exporter Math::BigFloat);
+@ISA = qw(Math::BigFloat);
-$VERSION = '0.14';
+$VERSION = '0.15';
use overload; # inherit overload from Math::BigFloat
my $nan = 'NaN';
my $class = 'Math::BigRat';
-my $IMPORT = 0;
sub isa
{
my $nf = Math::BigFloat->new($n,undef,undef);
$self->{sign} = '+';
return $self->bnan() if $nf->is_nan();
+
$self->{_n} = $MBI->_copy( $nf->{_m} ); # get mantissa
# now correct $self->{_n} due to $n
{
$d = Math::BigInt->new($d,undef,undef) unless ref $d;
$n = Math::BigInt->new($n,undef,undef) unless ref $n;
-
+
if ($n->{sign} =~ /^[+-]$/ && $d->{sign} =~ /^[+-]$/)
{
# both parts are ok as integers (wierd things like ' 1e0'
{
require Carp;
my $class = ref($self);
+ # "$self" below will stringify the object, this blows up if $self is a
+ # partial object (happens under trap_nan), so fix it beforehand
+ $self->{_d} = $MBI->_zero() unless defined $self->{_d};
+ $self->{_n} = $MBI->_zero() unless defined $self->{_n};
Carp::croak ("Tried to set $self to NaN in $class\::_bnan()");
}
$self->{_n} = $MBI->_zero();
{
require Carp;
my $class = ref($self);
+ # "$self" below will stringify the object, this blows up if $self is a
+ # partial object (happens under trap_nan), so fix it beforehand
+ $self->{_d} = $MBI->_zero() unless defined $self->{_d};
+ $self->{_n} = $MBI->_zero() unless defined $self->{_n};
Carp::croak ("Tried to set $self to inf in $class\::_binf()");
}
$self->{_n} = $MBI->_zero();
# 4 3 4*3 12
# we do not compute the gcd() here, but simple do:
- # 5 7 5*3 + 7*4 41
+ # 5 7 5*3 + 7*4 43
# - + - = --------- = --
# 4 3 4*3 12
# and bnorm() will then take care of the rest
+ # 5 * 3
$x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
+ # 7 * 4
my $m = $MBI->_mul( $MBI->_copy( $y->{_n} ), $x->{_d} );
+ # 5 * 3 + 7 * 4
($x->{_n}, $x->{sign}) = _e_add( $x->{_n}, $m, $x->{sign}, $y->{sign});
+ # 4 * 3
$x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
- # normalize and round
+ # normalize result, and possible round
$x->bnorm()->round(@r);
}
my $self = shift;
my $l = scalar @_;
my $lib = ''; my @a;
- $IMPORT++;
for ( my $i = 0; $i < $l ; $i++)
{
}
elsif ($_[$i] eq 'with')
{
- $MBI = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc
+ # this argument is no longer used
+ #$MBI = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc
$i++;
}
else
{
$_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
}
- # MBI already loaded, so feed it our lib arguments
- $MBI->import('lib' => $lib . join(",",@c), 'objectify');
+ $lib = join(",", @c);
}
+ my @import = ('objectify');
+ push @import, lib => $lib if $lib ne '';
+
+ # MBI already loaded, so feed it our lib arguments
+ Math::BigInt->import( @import );
$MBI = Math::BigFloat->config()->{lib};
# register us with MBI to get notified of future lib changes
Math::BigInt::_register_callback( $self, sub { $MBI = $_[0]; } );
- # any non :constant stuff is handled by our parent, Exporter
- # even if @_ is empty, to give it a chance
+ # any non :constant stuff is handled by our parent, Exporter (loaded
+ # by Math::BigFloat, even if @_ is empty, to give it a chance
$self->SUPER::import(@a); # for subclasses
$self->export_to_level(1,$self,@a); # need this, too
}
plan tests => 686;
}
-use Math::BigRat;
+use Math::BigRat lib => 'Calc';
use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL);
$class = "Math::BigRat";
# check that simple requiring BigRat works
use strict;
-use Test;
+use Test::More;
BEGIN
{
require Math::BigRat; $x = Math::BigRat->new(1); ++$x;
-ok ($x||'undef',2);
+is ($x, 2, '$x got successfully modified');
# all tests done
package bigint;
require 5.005;
-$VERSION = '0.06';
+$VERSION = '0.07';
use Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( );
my $self = shift;
# some defaults
- my $lib = 'Calc';
+ my $lib = '';
my @import = ( ':constant' ); # drive it w/ constant
my @a = @_; my $l = scalar @_; my $j = 0;
}
require Math::BigInt if $_lite == 0; # not already loaded?
$class = 'Math::BigInt'; # regardless of MBIL or not
- }
+ }
+ push @import, 'lib' => $lib if $lib ne '';
# Math::BigInt::Trace or plain Math::BigInt
- $class->import(@import, lib => $lib);
+ $class->import(@import);
bigint->accuracy($a) if defined $a;
bigint->precision($p) if defined $p;
package bignum;
require 5.005;
-$VERSION = '0.16';
+$VERSION = '0.17';
use Exporter;
@EXPORT_OK = qw( );
@EXPORT = qw( inf NaN );
my $self = shift;
# some defaults
- my $lib = 'Calc';
+ my $lib = '';
my $upgrade = 'Math::BigFloat';
my $downgrade = 'Math::BigInt';
}
require Math::BigInt if $_lite == 0; # not already loaded?
$class = 'Math::BigInt'; # regardless of MBIL or not
- }
+ }
+ push @import, 'lib' => $lib if $lib ne '';
# Math::BigInt::Trace or plain Math::BigInt
- $class->import(@import, upgrade => $upgrade, lib => $lib);
+ $class->import(@import, upgrade => $upgrade);
if ($trace)
{
package bigrat;
require 5.005;
-$VERSION = '0.07';
+$VERSION = '0.08';
require Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( );
# see also bignum->import() for additional comments
# some defaults
- my $lib = 'Calc'; my $upgrade = 'Math::BigFloat';
+ my $lib = ''; my $upgrade = 'Math::BigFloat';
my @import = ( ':constant' ); # drive it w/ constant
my @a = @_; my $l = scalar @_; my $j = 0;
require Math::BigInt if $_lite == 0; # not already loaded?
$class = 'Math::BigInt'; # regardless of MBIL or not
}
+ push @import, 'lib' => $lib if $lib ne '';
# Math::BigInt::Trace or plain Math::BigInt
- $class->import(@import, upgrade => $upgrade, lib => $lib);
+ $class->import(@import, upgrade => $upgrade);
require Math::BigFloat;
Math::BigFloat->import( upgrade => 'Math::BigRat', ':constant' );