# _p: precision
# _f: flags, used to signal MBI not to touch our private parts
-$VERSION = '1.42';
+$VERSION = '1.43';
require 5.005;
require Exporter;
##############################################################################
-# in case we call SUPER::->foo() and this wants to call modify()
-# sub modify () { 0; }
-
{
# valid method aliases for AUTOLOAD
my %methods = map { $_ => 1 }
/;
# valid method's that can be hand-ed up (for AUTOLOAD)
my %hand_ups = map { $_ => 1 }
- qw / is_nan is_inf is_negative is_positive
+ qw / is_nan is_inf is_negative is_positive is_pos is_neg
accuracy precision div_scale round_mode fneg fabs fnot
objectify upgrade downgrade
bone binf bnan bzero
/;
- sub method_alias { return exists $methods{$_[0]||''}; }
- sub method_hand_up { return exists $hand_ups{$_[0]||''}; }
+ sub method_alias { exists $methods{$_[0]||''}; }
+ sub method_hand_up { exists $hand_ups{$_[0]||''}; }
}
##############################################################################
if ($fallback)
{
# clear a/p after round, since user did not request it
- $x->{_a} = undef; $x->{_p} = undef;
+ delete $x->{_a}; delete $x->{_p};
}
# restore globals
$$abr = $ab; $$pbr = $pb;
# shortcut to not run through _find_round_parameters again
if (defined $params[0])
{
- $x->{_a} = undef; # clear before round
+ delete $x->{_a}; # clear before round
$x->bround($params[0],$params[2]); # then round accordingly
}
else
{
- $x->{_p} = undef; # clear before round
+ delete $x->{_p}; # clear before round
$x->bfround($params[1],$params[2]); # then round accordingly
}
if ($fallback)
{
# clear a/p after round, since user did not request it
- $x->{_a} = undef; $x->{_p} = undef;
+ delete $x->{_a}; delete $x->{_p};
}
if (wantarray)
if ($fallback)
{
# clear a/p after round, since user did not request it
- $rem->{_a} = undef; $rem->{_p} = undef;
+ delete $rem->{_a}; delete $rem->{_p};
}
return ($x,$rem);
}
if ($fallback)
{
# clear a/p after round, since user did not request it
- $x->{_a} = undef; $x->{_p} = undef;
+ delete $x->{_a}; delete $x->{_p};
}
# restore globals
$$abr = $ab; $$pbr = $pb;
if ($fallback)
{
# clear a/p after round, since user did not request it
- $x->{_a} = undef; $x->{_p} = undef;
+ delete $x->{_a}; delete $x->{_p};
}
# re-enable A and P, upgrade is taken care of by "local"
${"$self\::accuracy"} = $ab; ${"$self\::precision"} = $pb;
if ($fallback)
{
# clear a/p after round, since user did not request it
- $x->{_a} = undef; $x->{_p} = undef;
+ delete $x->{_a}; delete $x->{_p};
}
# restore globals
$$abr = $ab; $$pbr = $pb;
if ($fallback)
{
# clear a/p after round, since user did not request it
- $x->{_a} = undef; $x->{_p} = undef;
+ delete $x->{_a}; delete $x->{_p};
}
# restore globals
$$abr = $ab; $$pbr = $pb;
return $x if (defined $x->{_p} && $x->{_p} < 0 && $scale < $x->{_p});
$x->{_p} = $scale; # remember round in any case
- $x->{_a} = undef; # and clear A
+ delete $x->{_a}; # and clear A
if ($scale < 0)
{
# round right from the '.'
$x->{_m}->{sign} = $x->{sign};
$x->{_m}->bround($scale,$mode); # round mantissa
$x->{_m}->{sign} = '+'; # fix sign back
- # $x->{_m}->{_a} = undef; $x->{_m}->{_p} = undef;
$x->{_a} = $scale; # remember rounding
- $x->{_p} = undef; # and clear P
+ delete $x->{_p}; # and clear P
$x->bnorm(); # del trailing zeros gen. by bround()
}
# or falling back to MBI::bxxx()
my $name = $AUTOLOAD;
- $name =~ s/.*:://; # split package
+ $name =~ s/(.*):://; # split package
+ my $c = $1 || $class;
no strict 'refs';
- $class->import() if $IMPORT == 0;
+ $c->import() if $IMPORT == 0;
if (!method_alias($name))
{
if (!defined $name)
{
# delayed load of Carp and avoid recursion
require Carp;
- Carp::croak ("Can't call a method without name");
+ Carp::croak ("$c: Can't call a method without name");
}
if (!method_hand_up($name))
{
# delayed load of Carp and avoid recursion
require Carp;
- Carp::croak ("Can't call $class\-\>$name, not a valid method");
+ Carp::croak ("Can't call $c\-\>$name, not a valid method");
}
# try one level up, but subst. bxxx() for fxxx() since MBI only got bxxx()
$name =~ s/^f/b/;
return &{"$MBI"."::$name"}(@_);
}
my $bname = $name; $bname =~ s/^f/b/;
- *{$class."::$name"} = \&$bname;
- &$bname; # uses @_
+ $c .= "::$name";
+ *{$c} = \&{$bname};
+ &{$c}; # uses @_
}
sub exponent
$x->{_m}->{_f} = MB_NEVER_ROUND;
$x->{_e}->{_f} = MB_NEVER_ROUND;
# 'forget' that mantissa was rounded via MBI::bround() in MBF's bfround()
- $x->{_m}->{_a} = undef; $x->{_e}->{_a} = undef;
- $x->{_m}->{_p} = undef; $x->{_e}->{_p} = undef;
+ delete $x->{_m}->{_a}; delete $x->{_e}->{_a};
+ delete $x->{_m}->{_p}; delete $x->{_e}->{_p};
$x; # MBI bnorm is no-op, so dont call it
}
$x->is_one('-'); # true if arg is -1
$x->is_odd(); # true if odd, false for even
$x->is_even(); # true if even, false for odd
- $x->is_positive(); # true if >= 0
- $x->is_negative(); # true if < 0
+ $x->is_pos(); # true if >= 0
+ $x->is_neg(); # true if < 0
$x->is_inf(sign); # true if +inf, or -inf (default is '+')
$x->bcmp($y); # compare numbers (undef,<0,=0,>0)
$x->bstr(); # return string
$x->bsstr(); # return string in scientific notation
-
+
+ $x->as_int(); # return $x as BigInt
$x->exponent(); # return exponent as BigInt
$x->mantissa(); # return mantissa as BigInt
$x->parts(); # return (mantissa,exponent) as BigInt
my $class = "Math::BigInt";
require 5.005;
-$VERSION = '1.68';
+$VERSION = '1.69';
use Exporter;
@ISA = qw( Exporter );
@EXPORT_OK = qw( objectify bgcd blcm);
if (ref($x))
{
# $object->accuracy() or fallback to global
- $x->bround($a) if $a; # not for undef, 0
- $x->{_a} = $a; # set/overwrite, even if not rounded
- $x->{_p} = undef; # clear P
+ $x->bround($a) if $a; # not for undef, 0
+ $x->{_a} = $a; # set/overwrite, even if not rounded
+ delete $x->{_p}; # clear P
$a = ${"${class}::accuracy"} unless defined $a; # proper return value
}
else
{
- # set global
- ${"${class}::accuracy"} = $a;
- ${"${class}::precision"} = undef; # clear P
+ ${"${class}::accuracy"} = $a; # set global A
+ ${"${class}::precision"} = undef; # clear global P
}
- return $a; # shortcut
+ return $a; # shortcut
}
my $r;
if (ref($x))
{
# $object->precision() or fallback to global
- $x->bfround($p) if $p; # not for undef, 0
- $x->{_p} = $p; # set/overwrite, even if not rounded
- $x->{_a} = undef; # clear A
+ $x->bfround($p) if $p; # not for undef, 0
+ $x->{_p} = $p; # set/overwrite, even if not rounded
+ delete $x->{_a}; # clear A
$p = ${"${class}::precision"} unless defined $p; # proper return value
}
else
{
- # set global
- ${"${class}::precision"} = $p;
- ${"${class}::accuracy"} = undef; # clear A
+ ${"${class}::precision"} = $p; # set global P
+ ${"${class}::accuracy"} = undef; # clear global A
}
- return $p; # shortcut
+ return $p; # shortcut
}
my $r;
}
$self->{sign} = $nan;
delete $self->{_a}; delete $self->{_p}; # rounding NaN is silly
- return $self;
+ $self;
}
sub binf
$sign = $sign . 'inf' if $sign !~ /inf$/; # - => -inf
$self->{sign} = $sign;
($self->{_a},$self->{_p}) = @_; # take over requested rounding
- return $self;
+ $self;
}
sub bzero
# handle +-inf and NaN
return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
- return +1; # inf is always bigger
+ return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
+ return -1;
}
$CALC->_acmp($x->{value},$y->{value}); # lib does only 0,1,-1
}
($self,$x,$base,@r) = objectify(2,$class,@_);
}
+ return $x if $x->modify('blog');
+
# inf, -inf, NaN, <0 => NaN
return $x->bnan()
if $x->{sign} ne '+' || $base->{sign} ne '+';
sub digit
{
# return the nth decimal digit, negative values count backward, 0 is right
- my ($self,$x,$n) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
+ my ($self,$x,$n) = ref($_[0]) ? (undef,@_) : objectify(1,@_);
+ $n = $n->numify() if ref($n);
$CALC->_digit($x->{value},$n||0);
}
# if not: since we do not know underlying internal representation:
my $es = "$x"; $es =~ /([0]*)$/;
return 0 if !defined $1; # no zeros
- CORE::length("$1"); # as string, not as +0!
+ CORE::length("$1"); # $1 as string, not as +0!
}
sub bsqrt
{
# precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
# $n == 0 || $n == 1 => round to integer
- my $x = shift; $x = $class->new($x) unless ref $x;
+ my $x = shift; my $self = ref($x) || $x; $x = $self->new($x) unless ref $x;
my ($scale,$mode) = $x->_scale_p($x->precision(),$x->round_mode(),@_);
# no-op for BigInts if $n <= 0
$x->bround( $x->length()-$scale, $mode) if $scale > 0;
- $x->{_a} = undef; # bround sets {_a}
- $x->{_p} = $scale; # so correct it
+ delete $x->{_a}; # delete to save memory
+ $x->{_p} = $scale; # store new _p
$x;
}
=head1 AUTHORS
Original code by Mark Biggar, overloaded interface by Ilya Zakharevich.
-Completely rewritten by Tels http://bloodgate.com in late 2000, 2001, 2002
-and still at it in 2003.
+Completely rewritten by Tels http://bloodgate.com in late 2000, 2001 - 2003
+and still at it in 2004.
Many people contributed in one or more ways to the final beast, see the file
CREDITS for an (uncomplete) list. If you miss your name, please drop me a