Front page | perl.perl5.changes |
Postings from April 2008
Change 33715: Upgrade to Math::BigInt v1.89
From:
Rafael Garcia-Suarez
Date:
April 21, 2008 00:45
Subject:
Change 33715: Upgrade to Math::BigInt v1.89
Change 33715 by rgs@scipion on 2008/04/21 07:34:12
Upgrade to Math::BigInt v1.89
Affected files ...
... //depot/perl/lib/Math/BigFloat.pm#81 edit
... //depot/perl/lib/Math/BigInt.pm#91 edit
... //depot/perl/lib/Math/BigInt/t/bare_mbf.t#29 edit
... //depot/perl/lib/Math/BigInt/t/bare_mbi.t#30 edit
... //depot/perl/lib/Math/BigInt/t/bigfltpm.inc#39 edit
... //depot/perl/lib/Math/BigInt/t/bigfltpm.t#40 edit
... //depot/perl/lib/Math/BigInt/t/bigintpm.inc#37 edit
... //depot/perl/lib/Math/BigInt/t/bigintpm.t#46 edit
... //depot/perl/lib/Math/BigInt/t/calling.t#12 edit
... //depot/perl/lib/Math/BigInt/t/const_mbf.t#2 edit
... //depot/perl/lib/Math/BigInt/t/constant.t#9 edit
... //depot/perl/lib/Math/BigInt/t/mbimbf.t#18 edit
... //depot/perl/lib/Math/BigInt/t/sub_mbf.t#33 edit
... //depot/perl/lib/Math/BigInt/t/sub_mbi.t#35 edit
... //depot/perl/lib/Math/BigInt/t/with_sub.t#23 edit
Differences ...
==== //depot/perl/lib/Math/BigFloat.pm#81 (text) ====
Index: perl/lib/Math/BigFloat.pm
--- perl/lib/Math/BigFloat.pm#80~31875~ 2007-09-16 03:48:40.000000000 -0700
+++ perl/lib/Math/BigFloat.pm 2008-04-21 00:34:12.000000000 -0700
@@ -12,7 +12,7 @@
# _a : accuracy
# _p : precision
-$VERSION = '1.59';
+$VERSION = '1.60';
require 5.006;
require Exporter;
@@ -2142,8 +2142,9 @@
# But we need at least $scale digits, so calculate how many are missing
my $shift = $scale - $digits;
- # That should never happen (we take care of integer guesses above)
- # $shift = 0 if $shift < 0;
+ # This happens if the input had enough digits
+ # (we take care of integer guesses above)
+ $shift = 0 if $shift < 0;
# Multiply in steps of 100, by shifting left two times the "missing" digits
my $s2 = $shift * 2;
@@ -2846,12 +2847,49 @@
return $y->bnan() if ($y->{sign} eq $nan) || ($x->{sign} eq $nan);
- return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
-
# Y X
# 0 0 result is 0
# 0 +x result is 0
- return $y->bzero(@r) if $y->is_zero() && $x->{sign} eq '+';
+ # ? inf result is 0
+ return $y->bzero(@r) if ($x->is_inf('+') && !$y->is_inf()) || ($y->is_zero() && $x->{sign} eq '+');
+
+ # Y X
+ # != 0 -inf result is +- pi
+ if ($x->is_inf() || $y->is_inf())
+ {
+ # calculate PI
+ my $pi = $self->bpi(@r);
+ if ($y->is_inf())
+ {
+ # upgrade to BigRat etc.
+ return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
+ if ($x->{sign} eq '-inf')
+ {
+ # calculate 3 pi/4
+ $MBI->_mul($pi->{_m}, $MBI->_new(3));
+ $MBI->_div($pi->{_m}, $MBI->_new(4));
+ }
+ elsif ($x->{sign} eq '+inf')
+ {
+ # calculate pi/4
+ $MBI->_div($pi->{_m}, $MBI->_new(4));
+ }
+ else
+ {
+ # calculate pi/2
+ $MBI->_div($pi->{_m}, $MBI->_new(2));
+ }
+ $y->{sign} = substr($y->{sign},0,1); # keep +/-
+ }
+ # modify $y in place
+ $y->{_m} = $pi->{_m};
+ $y->{_e} = $pi->{_e};
+ $y->{_es} = $pi->{_es};
+ # keep the sign of $y
+ return $y;
+ }
+
+ return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
# Y X
# 0 -x result is PI
@@ -2859,7 +2897,7 @@
{
# calculate PI
my $pi = $self->bpi(@r);
- # modify $x in place
+ # modify $y in place
$y->{_m} = $pi->{_m};
$y->{_e} = $pi->{_e};
$y->{_es} = $pi->{_es};
@@ -2870,16 +2908,15 @@
# Y X
# +y 0 result is PI/2
# -y 0 result is -PI/2
- if ($y->is_inf() || $x->is_zero())
+ if ($x->is_zero())
{
# calculate PI/2
my $pi = $self->bpi(@r);
- # modify $x in place
+ # modify $y in place
$y->{_m} = $pi->{_m};
$y->{_e} = $pi->{_e};
$y->{_es} = $pi->{_es};
# -y => -PI/2, +y => PI/2
- $y->{sign} = substr($y->{sign},0,1); # +inf => +
$MBI->_div($y->{_m}, $MBI->_new(2));
return $y;
}
@@ -2918,7 +2955,7 @@
{
# 1,1 => PI/4
my $pi_4 = $self->bpi( $scale - 3);
- # modify $x in place
+ # modify $y in place
$y->{_m} = $pi_4->{_m};
$y->{_e} = $pi_4->{_e};
$y->{_es} = $pi_4->{_es};
@@ -3639,6 +3676,14 @@
return $x if $x->modify('as_number');
+ if (!$x->isa('Math::BigFloat'))
+ {
+ # if the object can as_number(), use it
+ return $x->as_number() if $x->can('as_number');
+ # otherwise, get us a float and then a number
+ $x = $x->can('as_float') ? $x->as_float() : $self->new(0+"$x");
+ }
+
my $z = $MBI->_copy($x->{_m});
if ($x->{_es} eq '-') # < 0
{
@@ -4146,14 +4191,19 @@
use Math::BigFloat lib => 'GMP';
+B<Note>: General purpose packages should not be explicit about the library
+to use; let the script author decide which is best.
+
Note: The keyword 'lib' will warn when the requested library could not be
loaded. To suppress the warning use 'try' instead:
use Math::BigFloat try => 'GMP';
-To turn the warning into a die(), use 'only' instead:
+If your script works with huge numbers and Calc is too slow for them,
+you can also for the loading of one of these libraries and if none
+of them can be used, the code will die:
- use Math::BigFloat only => 'GMP';
+ use Math::BigFloat only => 'GMP,Pari';
The following would first try to find Math::BigInt::Foo, then
Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
==== //depot/perl/lib/Math/BigInt.pm#91 (text) ====
Index: perl/lib/Math/BigInt.pm
--- perl/lib/Math/BigInt.pm#90~31951~ 2007-09-24 05:37:28.000000000 -0700
+++ perl/lib/Math/BigInt.pm 2008-04-21 00:34:12.000000000 -0700
@@ -18,7 +18,7 @@
my $class = "Math::BigInt";
use 5.006;
-$VERSION = '1.88';
+$VERSION = '1.89';
@ISA = qw(Exporter);
@EXPORT_OK = qw(objectify bgcd blcm);
@@ -3000,11 +3000,47 @@
return $y->bnan() if ($y->{sign} eq $nan) || ($x->{sign} eq $nan);
- return $y->bzero() if $y->is_zero() && $x->{sign} eq '+'; # x >= 0
-
- # inf handling
- # +-inf => --PI/2 => +-1
- return $y->bone( substr($y->{sign},0,1) ) if $y->{sign} =~ /^[+-]inf$/;
+ # Y X
+ # != 0 -inf result is +- pi
+ if ($x->is_inf() || $y->is_inf())
+ {
+ # upgrade to BigFloat etc.
+ return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
+ if ($y->is_inf())
+ {
+ if ($x->{sign} eq '-inf')
+ {
+ # calculate 3 pi/4 => 2.3.. => 2
+ $y->bone( substr($y->{sign},0,1) );
+ $y->bmul($self->new(2));
+ }
+ elsif ($x->{sign} eq '+inf')
+ {
+ # calculate pi/4 => 0.7 => 0
+ $y->bzero();
+ }
+ else
+ {
+ # calculate pi/2 => 1.5 => 1
+ $y->bone( substr($y->{sign},0,1) );
+ }
+ }
+ else
+ {
+ if ($x->{sign} eq '+inf')
+ {
+ # calculate pi/4 => 0.7 => 0
+ $y->bzero();
+ }
+ else
+ {
+ # PI => 3.1415.. => 3
+ $y->bone( substr($y->{sign},0,1) );
+ $y->bmul($self->new(3));
+ }
+ }
+ return $y;
+ }
return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
@@ -3056,9 +3092,10 @@
use Math::BigInt;
- # or make it faster: install (optional) Math::BigInt::GMP
- # and always use (it will fall back to pure Perl if the
- # GMP library is not installed):
+ # or make it faster with huge numbers: install (optional)
+ # Math::BigInt::GMP and always use (it will fall back to
+ # pure Perl if the GMP library is not installed):
+ # (See also the L<MATH LIBRARY> section!)
# will warn if Math::BigInt::GMP cannot be found
use Math::BigInt lib => 'GMP';
@@ -3066,6 +3103,9 @@
# to supress the warning use this:
# use Math::BigInt try => 'GMP';
+ # dies if GMP cannot be loaded:
+ # use Math::BigInt only => 'GMP';
+
my $str = '1234567890';
my @values = (64,74,18);
my $n = 1; my $sign = '-';
@@ -4390,26 +4430,46 @@
Math with the numbers is done (by default) by a module called
C<Math::BigInt::Calc>. This is equivalent to saying:
- use Math::BigInt lib => 'Calc';
+ use Math::BigInt try => 'Calc';
+
+You can change this backend library by using:
-You can change this by using:
+ use Math::BigInt try => 'GMP';
- use Math::BigInt lib => 'BitVect';
+B<Note>: General purpose packages should not be explicit about the library
+to use; let the script author decide which is best.
+
+If your script works with huge numbers and Calc is too slow for them,
+you can also for the loading of one of these libraries and if none
+of them can be used, the code will die:
+
+ use Math::BigInt only => 'GMP,Pari';
The following would first try to find Math::BigInt::Foo, then
Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
- use Math::BigInt lib => 'Foo,Math::BigInt::Bar';
+ use Math::BigInt try => 'Foo,Math::BigInt::Bar';
+
+The library that is loaded last will be used. Note that this can be
+overwritten at any time by loading a different library, and numbers
+constructed with different libraries cannot be used in math operations
+together.
+
+=head3 What library to use?
-Since Math::BigInt::GMP is in almost all cases faster than Calc (especially in
-math involving really big numbers, where it is B<much> faster), and there is
-no penalty if Math::BigInt::GMP is not installed, it is a good idea to always
-use the following:
+B<Note>: General purpose packages should not be explicit about the library
+to use; let the script author decide which is best.
- use Math::BigInt lib => 'GMP';
+L<Math::BigInt::GMP> and L<Math::BigInt::Pari> are in cases involving big
+numbers much faster than Calc, however it is slower when dealing with very
+small numbers (less than about 20 digits) and when converting very large
+numbers to decimal (for instance for printing, rounding, calculating their
+length in decimal etc).
-Different low-level libraries use different formats to store the
-numbers. You should B<NOT> depend on the number having a specific format
+So please select carefully what libary you want to use.
+
+Different low-level libraries use different formats to store the numbers.
+However, you should B<NOT> depend on the number having a specific format
internally.
See the respective math library module documentation for further details.
@@ -4571,11 +4631,8 @@
=head2 Alternative math libraries
-You can use an alternative library to drive Math::BigInt via:
-
- use Math::BigInt lib => 'Module';
-
-See L<MATH LIBRARY> for more information.
+You can use an alternative library to drive Math::BigInt. See the section
+L<MATH LIBRARY> for more information.
For more benchmark results see L<http://bloodgate.com/perl/benchmarks.html>.
==== //depot/perl/lib/Math/BigInt/t/bare_mbf.t#29 (text) ====
Index: perl/lib/Math/BigInt/t/bare_mbf.t
--- perl/lib/Math/BigInt/t/bare_mbf.t#28~31478~ 2007-06-27 05:51:22.000000000 -0700
+++ perl/lib/Math/BigInt/t/bare_mbf.t 2008-04-21 00:34:12.000000000 -0700
@@ -27,7 +27,7 @@
}
print "# INC = @INC\n";
- plan tests => 2292;
+ plan tests => 2308;
}
use Math::BigFloat lib => 'BareCalc';
==== //depot/perl/lib/Math/BigInt/t/bare_mbi.t#30 (text) ====
Index: perl/lib/Math/BigInt/t/bare_mbi.t
--- perl/lib/Math/BigInt/t/bare_mbi.t#29~31478~ 2007-06-27 05:51:22.000000000 -0700
+++ perl/lib/Math/BigInt/t/bare_mbi.t 2008-04-21 00:34:12.000000000 -0700
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 3257;
+ plan tests => 3273;
}
use Math::BigInt lib => 'BareCalc';
==== //depot/perl/lib/Math/BigInt/t/bigfltpm.inc#39 (text) ====
Index: perl/lib/Math/BigInt/t/bigfltpm.inc
--- perl/lib/Math/BigInt/t/bigfltpm.inc#38~32590~ 2007-12-06 07:45:29.000000000 -0800
+++ perl/lib/Math/BigInt/t/bigfltpm.inc 2008-04-21 00:34:12.000000000 -0700
@@ -450,6 +450,14 @@
1:NaN:10:NaN
inf:1:14:1.5707963267949
-inf:1:14:-1.5707963267949
+0:-inf:14:3.1415926535898
+-1:-inf:14:-3.1415926535898
+1:-inf:14:3.1415926535898
+0:inf:14:0
+inf:-inf:14:2.3561944901923
+-inf:-inf:14:-2.3561944901923
+inf:+inf:14:0.7853981633974
+-inf:+inf:14:-0.7853981633974
1:5:13:0.1973955598499
1:5:14:0.19739555984988
0:0:10:0
==== //depot/perl/lib/Math/BigInt/t/bigfltpm.t#40 (xtext) ====
Index: perl/lib/Math/BigInt/t/bigfltpm.t
--- perl/lib/Math/BigInt/t/bigfltpm.t#39~31478~ 2007-06-27 05:51:22.000000000 -0700
+++ perl/lib/Math/BigInt/t/bigfltpm.t 2008-04-21 00:34:12.000000000 -0700
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 2292
+ plan tests => 2308
+ 5; # own tests
}
==== //depot/perl/lib/Math/BigInt/t/bigintpm.inc#37 (text) ====
Index: perl/lib/Math/BigInt/t/bigintpm.inc
--- perl/lib/Math/BigInt/t/bigintpm.inc#36~32590~ 2007-12-06 07:45:29.000000000 -0800
+++ perl/lib/Math/BigInt/t/bigintpm.inc 2008-04-21 00:34:12.000000000 -0700
@@ -2304,6 +2304,15 @@
1:NaN:10:NaN
inf:1:14:1
-inf:1:14:-1
+0:-inf:14:3
+-1:-inf:14:-3
+1:-inf:14:3
+0:inf:14:0
+inf:-inf:14:2
+-inf:-inf:14:-2
+# +- 0.78....
+inf:+inf:14:0
+-inf:+inf:14:0
1:5:13:0
1:5:14:0
0:0:10:0
==== //depot/perl/lib/Math/BigInt/t/bigintpm.t#46 (xtext) ====
Index: perl/lib/Math/BigInt/t/bigintpm.t
--- perl/lib/Math/BigInt/t/bigintpm.t#45~31609~ 2007-07-13 06:45:35.000000000 -0700
+++ perl/lib/Math/BigInt/t/bigintpm.t 2008-04-21 00:34:12.000000000 -0700
@@ -10,7 +10,7 @@
my $location = $0; $location =~ s/bigintpm.t//;
unshift @INC, $location; # to locate the testing files
chdir 't' if -d 't';
- plan tests => 3257 + 6;
+ plan tests => 3273 + 6;
}
use Math::BigInt lib => 'Calc';
==== //depot/perl/lib/Math/BigInt/t/calling.t#12 (text) ====
Index: perl/lib/Math/BigInt/t/calling.t
--- perl/lib/Math/BigInt/t/calling.t#11~31879~ 2007-09-17 04:09:56.000000000 -0700
+++ perl/lib/Math/BigInt/t/calling.t 2008-04-21 00:34:12.000000000 -0700
@@ -32,11 +32,6 @@
print "# INC = @INC\n";
my $tests = 160;
plan tests => $tests;
- if ($] < 5.006)
- {
- for (1..$tests) { skip (1,'Not supported on older Perls'); }
- exit;
- }
}
package Math::BigInt::Test;
==== //depot/perl/lib/Math/BigInt/t/const_mbf.t#2 (text) ====
Index: perl/lib/Math/BigInt/t/const_mbf.t
--- perl/lib/Math/BigInt/t/const_mbf.t#1~21861~ 2003-12-06 12:58:12.000000000 -0800
+++ perl/lib/Math/BigInt/t/const_mbf.t 2008-04-21 00:34:12.000000000 -0700
@@ -29,11 +29,6 @@
print "# INC = @INC\n";
plan tests => 2;
- if ($] < 5.006)
- {
- for (1..2) { skip (1,'Not supported on older Perls'); }
- exit;
- }
}
use Math::BigFloat ':constant';
==== //depot/perl/lib/Math/BigInt/t/constant.t#9 (text) ====
Index: perl/lib/Math/BigInt/t/constant.t
--- perl/lib/Math/BigInt/t/constant.t#8~21861~ 2003-12-06 12:58:12.000000000 -0800
+++ perl/lib/Math/BigInt/t/constant.t 2008-04-21 00:34:12.000000000 -0700
@@ -27,11 +27,6 @@
print "# INC = @INC\n";
plan tests => 7;
- if ($] < 5.006)
- {
- for (1..7) { skip (1,'Not supported on older Perls'); }
- exit;
- }
}
use Math::BigInt ':constant';
==== //depot/perl/lib/Math/BigInt/t/mbimbf.t#18 (text) ====
Index: perl/lib/Math/BigInt/t/mbimbf.t
--- perl/lib/Math/BigInt/t/mbimbf.t#17~22344~ 2004-02-19 13:17:10.000000000 -0800
+++ perl/lib/Math/BigInt/t/mbimbf.t 2008-04-21 00:34:12.000000000 -0700
@@ -32,7 +32,7 @@
print "# INC = @INC\n";
plan tests => 684
- + 23; # own tests
+ + 26; # own tests
}
use Math::BigInt 1.70;
@@ -100,3 +100,11 @@
$x = $x->blog(Math::BigInt->new(10));
ok ($x,2);
+
+# bug until v1.88 for sqrt() with enough digits
+for my $i (80,88,100)
+ {
+ $x = Math::BigFloat->new("1." . ("0" x $i) . "1");
+ $x = $x->bsqrt;
+ ok ($x, 1);
+ }
==== //depot/perl/lib/Math/BigInt/t/sub_mbf.t#33 (xtext) ====
Index: perl/lib/Math/BigInt/t/sub_mbf.t
--- perl/lib/Math/BigInt/t/sub_mbf.t#32~31478~ 2007-06-27 05:51:22.000000000 -0700
+++ perl/lib/Math/BigInt/t/sub_mbf.t 2008-04-21 00:34:12.000000000 -0700
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 2292
+ plan tests => 2308
+ 6; # + our own tests
}
==== //depot/perl/lib/Math/BigInt/t/sub_mbi.t#35 (xtext) ====
Index: perl/lib/Math/BigInt/t/sub_mbi.t
--- perl/lib/Math/BigInt/t/sub_mbi.t#34~31478~ 2007-06-27 05:51:22.000000000 -0700
+++ perl/lib/Math/BigInt/t/sub_mbi.t 2008-04-21 00:34:12.000000000 -0700
@@ -26,7 +26,7 @@
}
print "# INC = @INC\n";
- plan tests => 3257
+ plan tests => 3273
+ 5; # +5 own tests
}
==== //depot/perl/lib/Math/BigInt/t/with_sub.t#23 (text) ====
Index: perl/lib/Math/BigInt/t/with_sub.t
--- perl/lib/Math/BigInt/t/with_sub.t#22~31478~ 2007-06-27 05:51:22.000000000 -0700
+++ perl/lib/Math/BigInt/t/with_sub.t 2008-04-21 00:34:12.000000000 -0700
@@ -28,7 +28,7 @@
}
print "# INC = @INC\n";
- plan tests => 2292
+ plan tests => 2308
+ 1;
}
End of Patch.
-
Change 33715: Upgrade to Math::BigInt v1.89
by Rafael Garcia-Suarez