summaryrefslogtreecommitdiff
path: root/lib/Math/BigFloat.pm
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>2003-12-30 16:04:47 +0000
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2003-12-30 16:04:47 +0000
commit3a427a117ca05296a5c3d5d88415dc040792253b (patch)
tree97b20e515ab702aaaef8d8dbca74023d2d6c6b0f /lib/Math/BigFloat.pm
parentf5c235e79ea25787354a22de0af257a672e955a0 (diff)
downloadperl-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.pm40
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;