From 27e7b8bb4225378079f42e58c59f6131c62cace5 Mon Sep 17 00:00:00 2001 From: Tels Date: Fri, 12 Mar 2004 19:02:30 +0100 Subject: [PATCH] Math::BigInt v1.70, bignum 0.15, Math::BigRat 0.12 Message-Id: <200403121802.31679@bloodgate.com> p4raw-id: //depot/perl@22491 --- MANIFEST | 1 + lib/Math/BigFloat.pm | 25 ++++++++-- lib/Math/BigInt/t/_e_math.t | 111 +++++++++++++++++++++++++++++++++++++++++ lib/Math/BigInt/t/bare_mbf.t | 2 +- lib/Math/BigInt/t/bigfltpm.inc | 5 ++ lib/Math/BigInt/t/bigfltpm.t | 2 +- lib/Math/BigInt/t/sub_mbf.t | 2 +- lib/Math/BigInt/t/with_sub.t | 2 +- lib/bigint.pm | 4 +- lib/bignum.pm | 4 +- 10 files changed, 145 insertions(+), 13 deletions(-) create mode 100644 lib/Math/BigInt/t/_e_math.t diff --git a/MANIFEST b/MANIFEST index 91479a5..f34a3bd 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1351,6 +1351,7 @@ lib/Math/BigFloat/Trace.pm bignum tracing lib/Math/BigInt/CalcEmu.pm Pure Perl module to support Math::BigInt lib/Math/BigInt/Calc.pm Pure Perl module to support Math::BigInt lib/Math/BigInt.pm An arbitrary precision integer arithmetic package +lib/Math/BigInt/t/_e_math.t Helper routine in BigFloat for _e math lib/Math/BigInt/t/alias.inc Support for BigInt tests lib/Math/BigInt/t/bare_mbf.t Test MBF under Math::BigInt::BareCalc lib/Math/BigInt/t/bare_mbi.t Test MBI under Math::BigInt::BareCalc diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index a4ddd38..f7008aa 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -67,6 +67,7 @@ my $LOG_10_A = length($LOG_10)-1; my $LOG_2 = '0.6931471805599453094172321214581765680755001343602552541206800094933936220'; my $LOG_2_A = length($LOG_2)-1; +my $HALF = '0.5'; # made into an object if necc. ############################################################################## # the old code had $rnd_mode, so we need to support it, too @@ -1043,10 +1044,11 @@ sub _log_10 ### Since $x in the range 0.5 .. 1.5 is MUCH faster, we do a repeated div ### or mul by 2 (maximum times 3, since x < 10 and x > 0.1) - my $half = $self->new('0.5'); + $HALF = $self->new($HALF) unless ref($HALF); + my $twos = 0; # default: none (0 times) my $two = $self->new(2); - while ($x->bacmp($half) <= 0) + while ($x->bacmp($HALF) <= 0) { $twos--; $x->bmul($two); } @@ -1506,9 +1508,20 @@ sub broot local $Math::BigInt::upgrade = undef; # should be really parent class vs MBI # remember sign and make $x positive, since -4 ** (1/2) => -2 - my $sign = 0; $sign = 1 if $x->{sign} eq '-'; $x->babs(); + my $sign = 0; $sign = 1 if $x->{sign} eq '-'; $x->{sign} = '+'; + + my $is_two = 0; + if ($y->isa('Math::BigFloat')) + { + $is_two = ($y->{sign} eq '+' && $MBI->_is_two($y->{_m}) && $MBI->_is_zero($y->{_e})); + } + else + { + $is_two = ($y == 2); + } - if ($y->bcmp(2) == 0) # normal square root + # normal square root if $y == 2: + if ($is_two) { $x->bsqrt($scale+4); } @@ -1770,7 +1783,8 @@ sub _pow my $self = ref($x); # if $y == 0.5, it is sqrt($x) - return $x->bsqrt($a,$p,$r,$y) if $y->bcmp('0.5') == 0; + $HALF = $self->new($HALF) unless ref($HALF); + return $x->bsqrt($a,$p,$r,$y) if $y->bcmp($HALF) == 0; # Using: # a ** x == e ** (x * ln a) @@ -2342,6 +2356,7 @@ sub bnorm if ($MBI->_acmp($x->{_e},$z) >= 0) { $x->{_e} = $MBI->_sub ($x->{_e}, $z); + $x->{_es} = '+' if $MBI->_is_zero($x->{_e}); } else { diff --git a/lib/Math/BigInt/t/_e_math.t b/lib/Math/BigInt/t/_e_math.t new file mode 100644 index 0000000..3db3318 --- /dev/null +++ b/lib/Math/BigInt/t/_e_math.t @@ -0,0 +1,111 @@ +#!/usr/bin/perl -w + +# test the helper math routines in Math::BigFloat + +use Test::More; +use strict; + +BEGIN + { + $| = 1; + # to locate the testing files + my $location = $0; $location =~ s/_e_math.t//i; + if ($ENV{PERL_CORE}) + { + # testing with the core distribution + @INC = qw(../lib); + } + unshift @INC, '../lib'; + if (-d 't') + { + chdir 't'; + require File::Spec; + unshift @INC, File::Spec->catdir(File::Spec->updir, $location); + } + else + { + unshift @INC, $location; + } + print "# INC = @INC\n"; + + plan tests => 26; + } + +use Math::BigFloat; + +############################################################################# +# add + +my $a = Math::BigInt::Calc->_new("123"); +my $b = Math::BigInt::Calc->_new("321"); + +my ($x, $xs) = Math::BigFloat::_e_add($a,$b,'+','+'); +is (_str($x,$xs), '+444', 'add two positive numbers'); +is (_str($a,''), '444', 'a modified'); + +($x,$xs) = _add (123,321,'+','+'); +is (_str($x,$xs), '+444', 'add two positive numbers'); + +($x,$xs) = _add (123,321,'+','-'); +is (_str($x,$xs), '-198', 'add +x + -y'); +($x,$xs) = _add (123,321,'-','+'); +is (_str($x,$xs), '+198', 'add -x + +y'); + +($x,$xs) = _add (321,123,'-','+'); +is (_str($x,$xs), '-198', 'add -x + +y'); +($x,$xs) = _add (321,123,'+','-'); +is (_str($x,$xs), '+198', 'add +x + -y'); + +($x,$xs) = _add (10,1,'+','-'); +is (_str($x,$xs), '+9', 'add 10 + -1'); +($x,$xs) = _add (10,1,'-','+'); +is (_str($x,$xs), '-9', 'add -10 + +1'); +($x,$xs) = _add (1,10,'-','+'); +is (_str($x,$xs), '+9', 'add -1 + 10'); +($x,$xs) = _add (1,10,'+','-'); +is (_str($x,$xs), '-9', 'add 1 + -10'); + +############################################################################# +# sub + +$a = Math::BigInt::Calc->_new("123"); +$b = Math::BigInt::Calc->_new("321"); +($x, $xs) = Math::BigFloat::_e_sub($b,$a,'+','+'); +is (_str($x,$xs), '+198', 'sub two positive numbers'); +is (_str($b,''), '198', 'a modified'); + +($x,$xs) = _sub (123,321,'+','-'); +is (_str($x,$xs), '+444', 'sub +x + -y'); +($x,$xs) = _sub (123,321,'-','+'); +is (_str($x,$xs), '-444', 'sub -x + +y'); + +sub _add + { + my ($a,$b,$as,$bs) = @_; + + my $aa = Math::BigInt::Calc->_new($a); + my $bb = Math::BigInt::Calc->_new($b); + my ($x, $xs) = Math::BigFloat::_e_add($aa,$bb,$as,$bs); + is (Math::BigInt::Calc->_str($x), Math::BigInt::Calc->_str($aa), + 'param0 modified'); + ($x,$xs); + } + +sub _sub + { + my ($a,$b,$as,$bs) = @_; + + my $aa = Math::BigInt::Calc->_new($a); + my $bb = Math::BigInt::Calc->_new($b); + my ($x, $xs) = Math::BigFloat::_e_sub($aa,$bb,$as,$bs); + is (Math::BigInt::Calc->_str($x), Math::BigInt::Calc->_str($aa), + 'param0 modified'); + ($x,$xs); + } + +sub _str + { + my ($x,$s) = @_; + + $s . Math::BigInt::Calc->_str($x); + } diff --git a/lib/Math/BigInt/t/bare_mbf.t b/lib/Math/BigInt/t/bare_mbf.t index 9f94671..cbca372 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 => 1814; + plan tests => 1815; } use Math::BigFloat lib => 'BareCalc'; diff --git a/lib/Math/BigInt/t/bigfltpm.inc b/lib/Math/BigInt/t/bigfltpm.inc index d307ee6..5e1c19f 100644 --- a/lib/Math/BigInt/t/bigfltpm.inc +++ b/lib/Math/BigInt/t/bigfltpm.inc @@ -252,6 +252,11 @@ $class->precision(-3); $x = $class->new(12); $x->fsqrt(); ok ($x,'3.464'); ok ($class->new(-1)->is_one(),0); ok ($class->new(-1)->is_one('-'),1); +############################################################################# +# bug 1/0.5 leaving 2e-0 instead of 2e0 + +ok ($class->new(1)->fdiv('0.5')->bsstr(),'2e+0'); + 1; # all done ############################################################################### diff --git a/lib/Math/BigInt/t/bigfltpm.t b/lib/Math/BigInt/t/bigfltpm.t index 3fce460..9e50f5e 100755 --- a/lib/Math/BigInt/t/bigfltpm.t +++ b/lib/Math/BigInt/t/bigfltpm.t @@ -26,7 +26,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 1814 + plan tests => 1815 + 2; # own tests } diff --git a/lib/Math/BigInt/t/sub_mbf.t b/lib/Math/BigInt/t/sub_mbf.t index 9a8b9a3..8550a97 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 => 1814 + plan tests => 1815 + 6; # + our own tests } diff --git a/lib/Math/BigInt/t/with_sub.t b/lib/Math/BigInt/t/with_sub.t index d7391d9..3d48030 100644 --- a/lib/Math/BigInt/t/with_sub.t +++ b/lib/Math/BigInt/t/with_sub.t @@ -28,7 +28,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 1814 + plan tests => 1815 + 1; } diff --git a/lib/bigint.pm b/lib/bigint.pm index 6738a03..73923ee 100644 --- a/lib/bigint.pm +++ b/lib/bigint.pm @@ -1,7 +1,7 @@ package bigint; require 5.005; -$VERSION = '0.04'; +$VERSION = '0.05'; use Exporter; @ISA = qw( Exporter ); @EXPORT_OK = qw( ); @@ -379,6 +379,6 @@ as L, L and L. =head1 AUTHORS -(C) by Tels L in early 2002. +(C) by Tels L in early 2002, 2003. =cut diff --git a/lib/bignum.pm b/lib/bignum.pm index 056b45f..1902d58 100644 --- a/lib/bignum.pm +++ b/lib/bignum.pm @@ -1,7 +1,7 @@ package bignum; require 5.005; -$VERSION = '0.14'; +$VERSION = '0.15'; use Exporter; @EXPORT_OK = qw( ); @EXPORT = qw( inf NaN ); @@ -476,6 +476,6 @@ as L, L and L. =head1 AUTHORS -(C) by Tels L in early 2002. +(C) by Tels L in early 2002, 2003. =cut -- 2.7.4