diff options
author | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2003-12-30 16:04:47 +0000 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2003-12-30 16:04:47 +0000 |
commit | 3a427a117ca05296a5c3d5d88415dc040792253b (patch) | |
tree | 97b20e515ab702aaaef8d8dbca74023d2d6c6b0f /lib/Math/BigFloat.pm | |
parent | f5c235e79ea25787354a22de0af257a672e955a0 (diff) | |
download | perl-3a427a117ca05296a5c3d5d88415dc040792253b.tar.gz |
Upgrade to Math::BigInt 1.68.
p4raw-id: //depot/perl@22007
Diffstat (limited to 'lib/Math/BigFloat.pm')
-rw-r--r-- | lib/Math/BigFloat.pm | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index 9071648b51..90d4767cea 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -14,7 +14,8 @@ package Math::BigFloat; $VERSION = '1.42'; require 5.005; -use Exporter; + +require Exporter; @ISA = qw(Exporter Math::BigInt); use strict; @@ -1366,7 +1367,14 @@ sub bmod sub broot { # calculate $y'th root of $x - my ($self,$x,$y,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(2,@_); + + # set up parameters + my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_); + # objectify is costly, so avoid it + if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) + { + ($self,$x,$y,$a,$p,$r) = objectify(2,@_); + } # NaN handling: $x ** 1/0, x or y NaN, or y inf/-inf or y == 0 return $x->bnan() if $x->{sign} !~ /^\+/ || $y->is_zero() || @@ -1425,9 +1433,31 @@ sub broot } else { - my $u = $self->bone()->bdiv($y,$scale+4); - delete $u->{_a}; delete $u->{_p}; # otherwise it conflicts - $x->bpow($u,$scale+4); # el cheapo + # calculate the broot() as integer result first, and if it fits, return + # it rightaway (but only if $x and $y are integer): + + my $done = 0; # not yet + if ($y->is_int() && $x->is_int()) + { + my $int = $x->{_m}->copy(); + $int->blsft($x->{_e},10) unless $x->{_e}->is_zero(); + $int->broot($y->as_number()); + # if ($exact) + if ($int->copy()->bpow($y) == $x) + { + # found result, return it + $x->{_m} = $int; + $x->{_e} = $MBI->bzero(); + $x->bnorm(); + $done = 1; + } + } + if ($done == 0) + { + my $u = $self->bone()->bdiv($y,$scale+4); + delete $u->{_a}; delete $u->{_p}; # otherwise it conflicts + $x->bpow($u,$scale+4); # el cheapo + } } $x->bneg() if $sign == 1; |