summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTels <nospam-abuse@bloodgate.com>2005-04-03 12:43:10 +0200
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2005-04-05 10:40:35 +0000
commit233f7bc03a8f0557d08657ec772040b570b403cd (patch)
tree79d51b536240e85541715cab4dfd5099e0bd29b5 /lib
parent43e4f2c68f8de551ce4632b5fbfb077a650c967e (diff)
downloadperl-233f7bc03a8f0557d08657ec772040b570b403cd.tar.gz
[Patch] Math::BigInt v1.76, Math::BigRat v0.15, bignum v0.17
Message-Id: <200504031043.12273@bloodgate.com> p4raw-id: //depot/perl@24155
Diffstat (limited to 'lib')
-rw-r--r--lib/Math/BigFloat.pm147
-rw-r--r--lib/Math/BigInt.pm87
-rw-r--r--lib/Math/BigInt/Calc.pm6
-rw-r--r--lib/Math/BigInt/t/_e_math.t2
-rw-r--r--lib/Math/BigInt/t/bare_mbf.t2
-rw-r--r--lib/Math/BigInt/t/bigfltpm.inc14
-rwxr-xr-xlib/Math/BigInt/t/bigfltpm.t4
-rwxr-xr-xlib/Math/BigInt/t/bigintpm.t2
-rw-r--r--lib/Math/BigInt/t/calling.t17
-rw-r--r--lib/Math/BigInt/t/config.t8
-rw-r--r--lib/Math/BigInt/t/req_mbf0.t6
-rw-r--r--lib/Math/BigInt/t/req_mbfw.t12
-rwxr-xr-xlib/Math/BigInt/t/sub_mbf.t4
-rw-r--r--lib/Math/BigInt/t/trap.t55
-rw-r--r--lib/Math/BigInt/t/with_sub.t4
-rw-r--r--lib/Math/BigRat.pm41
-rwxr-xr-xlib/Math/BigRat/t/bigratpm.t2
-rw-r--r--lib/Math/BigRat/t/requirer.t4
-rw-r--r--lib/bigint.pm9
-rw-r--r--lib/bignum.pm9
-rw-r--r--lib/bigrat.pm7
21 files changed, 294 insertions, 148 deletions
diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm
index 8143175870..2300ae480c 100644
--- a/lib/Math/BigFloat.pm
+++ b/lib/Math/BigFloat.pm
@@ -12,7 +12,7 @@ package Math::BigFloat;
# _a : accuracy
# _p : precision
-$VERSION = '1.49';
+$VERSION = '1.50';
require 5.005;
require Exporter;
@@ -47,7 +47,7 @@ $upgrade = undef;
$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;
@@ -135,16 +135,12 @@ sub new
# 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
@@ -1345,11 +1341,14 @@ sub bdiv
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
{
@@ -1443,7 +1442,10 @@ sub bmod
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
@@ -2716,28 +2718,27 @@ This might change in the future, so do not depend on it.
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>:
@@ -2751,8 +2752,8 @@ 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
@@ -2821,9 +2822,48 @@ C<as_number()>:
$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
@@ -3031,6 +3071,49 @@ C<badd()> etc. The first will modify $x, the second one won't:
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
diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm
index 1d31534dca..dc428e7763 100644
--- a/lib/Math/BigInt.pm
+++ b/lib/Math/BigInt.pm
@@ -18,10 +18,10 @@ package Math::BigInt;
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
@@ -162,8 +162,8 @@ $_trap_nan = 0; # are NaNs ok? set w/ config()
$_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
@@ -528,11 +528,10 @@ sub new
}
# 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);
@@ -663,7 +662,7 @@ sub binf
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');
@@ -2414,7 +2413,7 @@ sub import
{
$_ =~ 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)
{
@@ -2640,9 +2639,11 @@ sub modify () { 0; }
1;
__END__
+=pod
+
=head1 NAME
-Math::BigInt - Arbitrary size integer math package
+Math::BigInt - Arbitrary size integer/float math package
=head1 SYNOPSIS
@@ -2890,11 +2891,26 @@ Example:
$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.
@@ -2909,7 +2925,7 @@ represents the accuracy that will be in effect for $x:
$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
@@ -2924,35 +2940,46 @@ Math::BigInt.
=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.
diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm
index eb5ba98a67..56b6aab497 100644
--- a/lib/Math/BigInt/Calc.pm
+++ b/lib/Math/BigInt/Calc.pm
@@ -6,7 +6,7 @@ use strict;
use vars qw/$VERSION/;
-$VERSION = '0.45';
+$VERSION = '0.46';
# Package to store unsigned big integers in decimal and do math with them
@@ -36,7 +36,7 @@ $VERSION = '0.45';
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);
@@ -94,7 +94,7 @@ sub _base_len
}
}
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
diff --git a/lib/Math/BigInt/t/_e_math.t b/lib/Math/BigInt/t/_e_math.t
index 3db33183a8..b3eb644437 100644
--- a/lib/Math/BigInt/t/_e_math.t
+++ b/lib/Math/BigInt/t/_e_math.t
@@ -31,7 +31,7 @@ BEGIN
plan tests => 26;
}
-use Math::BigFloat;
+use Math::BigFloat lib => 'Calc';
#############################################################################
# add
diff --git a/lib/Math/BigInt/t/bare_mbf.t b/lib/Math/BigInt/t/bare_mbf.t
index 9a12572e14..29a73a0153 100644
--- a/lib/Math/BigInt/t/bare_mbf.t
+++ b/lib/Math/BigInt/t/bare_mbf.t
@@ -27,7 +27,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 1992;
+ plan tests => 2012;
}
use Math::BigFloat lib => 'BareCalc';
diff --git a/lib/Math/BigInt/t/bigfltpm.inc b/lib/Math/BigInt/t/bigfltpm.inc
index 5f27a8b8cb..4099521fe7 100644
--- a/lib/Math/BigInt/t/bigfltpm.inc
+++ b/lib/Math/BigInt/t/bigfltpm.inc
@@ -1221,6 +1221,11 @@ NaNmul:-inf:NaN
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
@@ -1382,6 +1387,15 @@ abc:1: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
diff --git a/lib/Math/BigInt/t/bigfltpm.t b/lib/Math/BigInt/t/bigfltpm.t
index 5cc9ddbbda..c44402877b 100755
--- a/lib/Math/BigInt/t/bigfltpm.t
+++ b/lib/Math/BigInt/t/bigfltpm.t
@@ -26,11 +26,11 @@ BEGIN
}
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);
diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t
index 9923256a89..431ab02c3b 100755
--- a/lib/Math/BigInt/t/bigintpm.t
+++ b/lib/Math/BigInt/t/bigintpm.t
@@ -13,7 +13,7 @@ BEGIN
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";
diff --git a/lib/Math/BigInt/t/calling.t b/lib/Math/BigInt/t/calling.t
index 71c6b48c97..7376bad0f5 100644
--- a/lib/Math/BigInt/t/calling.t
+++ b/lib/Math/BigInt/t/calling.t
@@ -55,11 +55,11 @@ use overload;
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
@@ -106,7 +106,7 @@ $class = 'Math::BigInt';
$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
@@ -125,17 +125,6 @@ $ans = eval $try; ok ( $ans, "1024");
# 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
diff --git a/lib/Math/BigInt/t/config.t b/lib/Math/BigInt/t/config.t
index da75344f2a..68509c0e00 100644
--- a/lib/Math/BigInt/t/config.t
+++ b/lib/Math/BigInt/t/config.t
@@ -13,7 +13,7 @@ BEGIN
# 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';
@@ -105,16 +105,16 @@ foreach my $key (keys %$test)
##############################################################################
# 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
diff --git a/lib/Math/BigInt/t/req_mbf0.t b/lib/Math/BigInt/t/req_mbf0.t
index af312f1b92..90cd57cc9a 100644
--- a/lib/Math/BigInt/t/req_mbf0.t
+++ b/lib/Math/BigInt/t/req_mbf0.t
@@ -3,7 +3,7 @@
# check that simple requiring BigFloat and then bzero() works
use strict;
-use Test;
+use Test::More;
BEGIN
{
@@ -31,7 +31,9 @@ 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
diff --git a/lib/Math/BigInt/t/req_mbfw.t b/lib/Math/BigInt/t/req_mbfw.t
index 025722d277..10afc7a272 100644
--- a/lib/Math/BigInt/t/req_mbfw.t
+++ b/lib/Math/BigInt/t/req_mbfw.t
@@ -3,7 +3,7 @@
# check that requiring BigFloat and then calling import() works
use strict;
-use Test;
+use Test::More;
BEGIN
{
@@ -32,15 +32,17 @@ 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
diff --git a/lib/Math/BigInt/t/sub_mbf.t b/lib/Math/BigInt/t/sub_mbf.t
index 73d7fc0e21..3033ee2c66 100755
--- a/lib/Math/BigInt/t/sub_mbf.t
+++ b/lib/Math/BigInt/t/sub_mbf.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 1992
+ plan tests => 2012
+ 6; # + our own tests
}
@@ -34,7 +34,7 @@ use Math::BigFloat::Subclass;
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
diff --git a/lib/Math/BigInt/t/trap.t b/lib/Math/BigInt/t/trap.t
index af454092a2..94a7da4acb 100644
--- a/lib/Math/BigInt/t/trap.t
+++ b/lib/Math/BigInt/t/trap.t
@@ -3,14 +3,14 @@
# 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;
@@ -22,42 +22,54 @@ my ($cfg,$x);
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');
}
##############################################################################
@@ -65,17 +77,16 @@ foreach my $class ($mbi, $mbf)
$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
diff --git a/lib/Math/BigInt/t/with_sub.t b/lib/Math/BigInt/t/with_sub.t
index 0ed85a4f4c..07320a961f 100644
--- a/lib/Math/BigInt/t/with_sub.t
+++ b/lib/Math/BigInt/t/with_sub.t
@@ -28,11 +28,11 @@ BEGIN
}
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";
diff --git a/lib/Math/BigRat.pm b/lib/Math/BigRat.pm
index 523088a273..6243dd4c5a 100644
--- a/lib/Math/BigRat.pm
+++ b/lib/Math/BigRat.pm
@@ -16,14 +16,13 @@ package Math::BigRat;
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
@@ -61,7 +60,6 @@ my $MBI = 'Math::BigInt::Calc';
my $nan = 'NaN';
my $class = 'Math::BigRat';
-my $IMPORT = 0;
sub isa
{
@@ -201,6 +199,7 @@ sub new
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
@@ -245,7 +244,7 @@ sub new
{
$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'
@@ -448,6 +447,10 @@ sub _bnan
{
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();
@@ -463,6 +466,10 @@ sub _binf
{
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();
@@ -512,21 +519,25 @@ sub badd
# 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);
}
@@ -1305,7 +1316,6 @@ sub import
my $self = shift;
my $l = scalar @_;
my $lib = ''; my @a;
- $IMPORT++;
for ( my $i = 0; $i < $l ; $i++)
{
@@ -1333,7 +1343,8 @@ sub import
}
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
@@ -1351,17 +1362,21 @@ sub import
{
$_ =~ 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
}
diff --git a/lib/Math/BigRat/t/bigratpm.t b/lib/Math/BigRat/t/bigratpm.t
index 510bccd58b..465d698c37 100755
--- a/lib/Math/BigRat/t/bigratpm.t
+++ b/lib/Math/BigRat/t/bigratpm.t
@@ -29,7 +29,7 @@ BEGIN
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";
diff --git a/lib/Math/BigRat/t/requirer.t b/lib/Math/BigRat/t/requirer.t
index 6805658624..8be2fa831a 100644
--- a/lib/Math/BigRat/t/requirer.t
+++ b/lib/Math/BigRat/t/requirer.t
@@ -3,7 +3,7 @@
# check that simple requiring BigRat works
use strict;
-use Test;
+use Test::More;
BEGIN
{
@@ -35,7 +35,7 @@ my ($x);
require Math::BigRat; $x = Math::BigRat->new(1); ++$x;
-ok ($x||'undef',2);
+is ($x, 2, '$x got successfully modified');
# all tests done
diff --git a/lib/bigint.pm b/lib/bigint.pm
index 695b4c4bed..a53891af5c 100644
--- a/lib/bigint.pm
+++ b/lib/bigint.pm
@@ -1,7 +1,7 @@
package bigint;
require 5.005;
-$VERSION = '0.06';
+$VERSION = '0.07';
use Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( );
@@ -102,7 +102,7 @@ sub import
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;
@@ -162,9 +162,10 @@ sub import
}
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;
diff --git a/lib/bignum.pm b/lib/bignum.pm
index db03d98c90..951bf95041 100644
--- a/lib/bignum.pm
+++ b/lib/bignum.pm
@@ -1,7 +1,7 @@
package bignum;
require 5.005;
-$VERSION = '0.16';
+$VERSION = '0.17';
use Exporter;
@EXPORT_OK = qw( );
@EXPORT = qw( inf NaN );
@@ -63,7 +63,7 @@ sub import
my $self = shift;
# some defaults
- my $lib = 'Calc';
+ my $lib = '';
my $upgrade = 'Math::BigFloat';
my $downgrade = 'Math::BigInt';
@@ -140,9 +140,10 @@ sub import
}
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)
{
diff --git a/lib/bigrat.pm b/lib/bigrat.pm
index b2a26d68b1..8085b74d44 100644
--- a/lib/bigrat.pm
+++ b/lib/bigrat.pm
@@ -1,7 +1,7 @@
package bigrat;
require 5.005;
-$VERSION = '0.07';
+$VERSION = '0.08';
require Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( );
@@ -66,7 +66,7 @@ sub import
# 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;
@@ -138,8 +138,9 @@ sub import
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' );