From: Tels Date: Sun, 6 Jul 2003 15:41:36 +0000 (+0200) Subject: Upgrade BigInt and BigRat X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=93c87d9dc758ed6254c5eaa31718f40901b73ac0;p=p5sagit%2Fp5-mst-13.2.git Upgrade BigInt and BigRat Subject: BigInt v1.65, Bigrat v0.10 - reloaded Message-Id: <200307061158.23576@bloodgate.com> p4raw-id: //depot/perl@20041 --- diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index 4a5a74e..9dd4c1c 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -712,6 +712,7 @@ sub blog delete $x->{_a}; delete $x->{_p}; # need to disable $upgrade in BigInt, to avoid deep recursion local $Math::BigInt::upgrade = undef; + local $Math::BigFloat::downgrade = undef; # upgrade $x if $x is not a BigFloat (handle BigInt input) if (!$x->isa('Math::BigFloat')) @@ -725,6 +726,7 @@ sub blog # and if a different base was requested, convert it if (defined $base) { + $base = Math::BigFloat->new($base) unless $base->isa('Math::BigFloat'); # not ln, but some other base $x->bdiv( $base->copy()->blog(undef,$scale), $scale ); } diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm index fba83e2..dd9fda8 100644 --- a/lib/Math/BigInt.pm +++ b/lib/Math/BigInt.pm @@ -2197,7 +2197,7 @@ sub broot $x->badd($org / ($x ** 2)); $x->bdiv($divider); } - #print $x ** $y," org ",$org,"\n"; + #print $x ** $y," org ",$org,"\n"; # correct overshot while ($x ** $y < $org) { @@ -3119,8 +3119,14 @@ appropriate information. div_scale Fallback acccuracy for div 40 -It is currently not supported to set the configuration parameters by passing -a hash ref to C. +The following values can be set by passing config a reference to a hash: + + trap_inf trap_nan + upgrade downgrade precision accuracy round_mode div_scale + +Example: + + $new_cfg = Math::BigInt->config( { trap_inf => 1, precision => 5 } ); =head2 accuracy diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm index b1d88fa..a3091c7 100644 --- a/lib/Math/BigInt/Calc.pm +++ b/lib/Math/BigInt/Calc.pm @@ -8,7 +8,7 @@ require Exporter; use vars qw/@ISA $VERSION/; @ISA = qw(Exporter); -$VERSION = '0.34'; +$VERSION = '0.35'; # Package to store unsigned big integers in decimal and do math with them @@ -27,7 +27,7 @@ $VERSION = '0.34'; # Beware of things like: # $i = $i * $y + $car; $car = int($i / $MBASE); $i = $i % $MBASE; -# This works on x86, but fails on ARM (SA1100, iPAQ) due to whoeknows what +# This works on x86, but fails on ARM (SA1100, iPAQ) due to whoknows what # reasons. So, use this instead (slower, but correct): # $i = $i * $y + $car; $car = int($i / $MBASE); $i -= $MBASE * $car; diff --git a/lib/Math/BigInt/t/biglog.t b/lib/Math/BigInt/t/biglog.t index e79a5d2..c7c07c1 100644 --- a/lib/Math/BigInt/t/biglog.t +++ b/lib/Math/BigInt/t/biglog.t @@ -96,9 +96,7 @@ ok ($cl->new('1.2')->bpow('0.3',10), '1.056219968'); ok ($cl->new('10')->bpow('0.6',10), '3.981071706'); # blog should handle bigint input -# TODO: should be 2 -#ok (Math::BigFloat::blog(Math::BigInt->new(100),10), 2); -ok (Math::BigFloat::blog(Math::BigInt->new(100),10), 'NaN'); +ok (Math::BigFloat::blog(Math::BigInt->new(100),10), 2); ok (Math::BigInt->new(100)->blog(10), 'NaN'); # test for bug in bsqrt() not taking negative _e into account diff --git a/lib/Math/BigInt/t/mbimbf.t b/lib/Math/BigInt/t/mbimbf.t index bada2aa..17cd712 100644 --- a/lib/Math/BigInt/t/mbimbf.t +++ b/lib/Math/BigInt/t/mbimbf.t @@ -32,7 +32,7 @@ BEGIN print "# INC = @INC\n"; plan tests => 679 - + 22; # own tests + + 23; # own tests } use Math::BigInt 1.63; @@ -92,4 +92,12 @@ foreach my $class (qw/Math::BigInt Math::BigFloat/) # so the return value of that operation should # be 42, not undef ok ($x->accuracy(),42); # so $x should still have A = 42 + $class->accuracy(undef); # reset for further tests + $class->precision(undef); } + +# bug with flog(Math::BigFloat,Math::BigInt) +$x = Math::BigFloat->new(100); +$x = $x->blog(Math::BigInt->new(10)); + +ok ($x,2); diff --git a/lib/Math/BigRat.pm b/lib/Math/BigRat.pm index b00aed4..993c2a4 100644 --- a/lib/Math/BigRat.pm +++ b/lib/Math/BigRat.pm @@ -168,7 +168,7 @@ sub new $self->{sign} = '+'; return $self->bnan() if $self->{_n}->{sign} eq $nan || $self->{_d}->{sign} eq $nan; - # inf handling is missing here + # handle inf and NAN cases: if ($self->{_n}->is_inf() || $self->{_d}->is_inf()) { # inf/inf => NaN @@ -570,12 +570,13 @@ sub bmod # compute $x - $y * floor($x/$y), keeping the sign of $x + # locally disable these, since they would interfere local $Math::BigInt::upgrade = undef; local $Math::BigInt::accuracy = undef; local $Math::BigInt::precision = undef; my $u = $x->copy()->babs(); - # do a "normal" division ($x/$y) + # first, do a "normal" division ($x/$y) $u->{_d}->bmul($y->{_n}); $u->{_n}->bmul($y->{_d}); @@ -597,7 +598,6 @@ sub bmod $x->{sign} = $xsign; # put sign back $x->bnorm()->round(@r); - $x; } ############################################################################## @@ -908,8 +908,8 @@ sub bsqrt local $Math::BigInt::upgrade = undef; local $Math::BigInt::precision = undef; local $Math::BigInt::accuracy = undef; - $x->{_d} = Math::BigFloat->new($x->{_d})->bsqrt(@r); - $x->{_n} = Math::BigFloat->new($x->{_n})->bsqrt(@r); + $x->{_d} = Math::BigFloat->new($x->{_d})->bsqrt(); + $x->{_n} = Math::BigFloat->new($x->{_n})->bsqrt(); # if sqrt(D) was not integer if ($x->{_d}->{_e}->{sign} ne '+') @@ -921,7 +921,7 @@ sub bsqrt if ($x->{_n}->{_e}->{sign} ne '+') { $x->{_d}->blsft($x->{_n}->{_e}->babs(),10); # 71/45.1 => 710/45.1 - $x->{_n} = $x->{_n}->{_n}; # 710/45.1 => 710/451 + $x->{_n} = $x->{_n}->{_m}; # 710/45.1 => 710/451 } # convert parts to $MBI again @@ -1024,10 +1024,12 @@ sub numify return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, NaN, etc - my $t = Math::BigFloat->new($x->{_n}); - $t->bneg() if $x->is_negative(); - $t->bdiv($x->{_d}); - $t->numify(); + # N/1 => N + return $x->{_n}->numify() if $x->{_d}->is_one(); + + # N/D + my $neg = 1; $neg = -1 if $x->{sign} ne '+'; + $neg * $x->{_n}->numify() / $x->{_d}->numify(); # return sign * N/D } sub as_number @@ -1113,7 +1115,10 @@ sub import eval $rc; } } - die ("Couldn't load $MBI: $! $@") if $@; + if ($@) + { + require Carp; Carp::croak ("Couldn't load $MBI: $! $@"); + } # any non :constant stuff is handled by our parent, Exporter # even if @_ is empty, to give it a chance diff --git a/lib/Math/BigRat/t/bigrat.t b/lib/Math/BigRat/t/bigrat.t index dd6f8ad..ae38555 100755 --- a/lib/Math/BigRat/t/bigrat.t +++ b/lib/Math/BigRat/t/bigrat.t @@ -8,7 +8,7 @@ BEGIN $| = 1; chdir 't' if -d 't'; unshift @INC, '../lib'; # for running manually - plan tests => 159; + plan tests => 164; } # testing of Math::BigRat @@ -162,8 +162,20 @@ ok ($x*$y,'3/7'); $x = $cr->new('3/5'); $y = $cr->new('5/7'); ok ($x/$y,'21/25'); +$x = $cr->new('7/4'); $y = $cr->new('1'); +ok ($x % $y,'3/4'); + +$x = $cr->new('7/4'); $y = $cr->new('5/13'); +ok ($x % $y,'11/52'); + +$x = $cr->new('7/4'); $y = $cr->new('5/9'); +ok ($x % $y,'1/12'); + $x = $cr->new('-144/9')->bsqrt(); ok ($x,'NaN'); $x = $cr->new('144/9')->bsqrt(); ok ($x,'4'); +$x = $cr->new('3/4')->bsqrt(); ok ($x, + '1732050807568877293527446341505872366943/' + .'2000000000000000000000000000000000000000'); ############################################################################## # bpow @@ -222,6 +234,8 @@ $x = $cr->new('inf'); ok ($x->numify(), 'inf'); $x = $cr->new('-inf'); ok ($x->numify(), '-inf'); $x = $cr->new('NaN'); ok ($x->numify(), 'NaN'); +$x = $cr->new('4/3'); ok ($x->numify(), 4/3); + ############################################################################## # done diff --git a/lib/Math/BigRat/t/bigratpm.inc b/lib/Math/BigRat/t/bigratpm.inc index 8b706be..4e63220 100644 --- a/lib/Math/BigRat/t/bigratpm.inc +++ b/lib/Math/BigRat/t/bigratpm.inc @@ -214,12 +214,16 @@ NaN:NaN 2:-:-inf 3:abc:inf &numify -#0:0e+1 -#+1:1e+0 -#1234:1234e+0 +0:0 ++1:1 +1234:1234 +3/4:0.75 +5/2:2.5 +3/2:1.5 +5/4:1.25 NaN:NaN -#+inf:inf -#-inf:-inf ++inf:inf +-inf:-inf &fnan abc:NaN 2:NaN diff --git a/lib/Math/BigRat/t/bigratpm.t b/lib/Math/BigRat/t/bigratpm.t index befed73..7994332 100755 --- a/lib/Math/BigRat/t/bigratpm.t +++ b/lib/Math/BigRat/t/bigratpm.t @@ -26,7 +26,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 525; + plan tests => 534; } use Math::BigRat;