'+' => sub {new Math::BigFloat &fadd},
'-' => sub {new Math::BigFloat
$_[2]? fsub($_[1],${$_[0]}) : fsub(${$_[0]},$_[1])},
-'<=>' => sub {new Math::BigFloat
- $_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])},
-'cmp' => sub {new Math::BigFloat
- $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
+'<=>' => sub {$_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])},
+'cmp' => sub {$_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
'*' => sub {new Math::BigFloat &fmul},
'/' => sub {new Math::BigFloat
$_[2]? scalar fdiv($_[1],${$_[0]}) :
sub new {
my ($class) = shift;
my ($foo) = fnorm(shift);
- panic("Not a number initialized to Math::BigFloat") if $foo eq "NaN";
bless \$foo, $class;
}
+
sub numify { 0 + "${$_[0]}" } # Not needed, additional overhead
# comparing to direct compilation based on
# stringify
sub fnorm { #(string) return fnum_str
local($_) = @_;
s/\s+//g; # strip white space
+ local $^W = 0; # $4 and $5 below might legitimately be undefined
if (/^([+-]?)(\d*)(\.(\d*))?([Ee]([+-]?\d+))?$/ && "$2$4" ne '') {
&norm(($1 ? "$1$2$4" : "+$2$4"),(($4 ne '') ? $6-length($4) : $6));
} else {
$scale = length($xm)-1 if (length($xm)-1 > $scale);
$scale = length($ym)-1 if (length($ym)-1 > $scale);
$scale = $scale + length($ym) - length($xm);
- &norm(&round(Math::BigInt::bdiv($xm.('0' x $scale),$ym),$ym),
+ &norm(&round(Math::BigInt::bdiv($xm.('0' x $scale),$ym),
+ Math::BigInt::babs($ym)),
$xe-$ye-$scale);
}
}
if ($xe < 1) {
'+0E+0';
} elsif ($xe == 1) {
- &norm(&round('+0',"+0".substr($xm,$[+1,1),"+10"), $scale);
+ # The first substr preserves the sign, passing a non-
+ # normalized "-0" to &round when rounding -0.006 (for
+ # example), purely so &round won't lose the sign.
+ &norm(&round(substr($xm,$[,1).'0',
+ "+0".substr($xm,$[+1,1),"+10"), $scale);
} else {
&norm(&round(substr($xm,$[,$xe),
"+0".substr($xm,$[+$xe,1),"+10"), $scale);
=item number format
canonical strings have the form /[+-]\d+E[+-]\d+/ . Input values can
-have imbedded whitespace.
+have embedded whitespace.
=item Error returns 'NaN'
=item Division is computed to
-C<max($div_scale,length(dividend)+length(divisor))> digits by default.
+C<max($Math::BigFloat::div_scale,length(dividend)+length(divisor))>
+digits by default.
Also used for default sqrt scale.
+=item Rounding is performed
+
+according to the value of
+C<$Math::BigFloat::rnd_mode>:
+
+ trunc truncate the value
+ zero round towards 0
+ +inf round towards +infinity (round up)
+ -inf round towards -infinity (round down)
+ even round to the nearest, .5 to the even digit
+ odd round to the nearest, .5 to the odd digit
+
+The default is C<even> rounding.
+
=back
=head1 BUGS
The current version of this module is a preliminary version of the
real thing that is currently (as of perl5.002) under development.
+The printf subroutine does not use the value of
+C<$Math::BigFloat::rnd_mode> when rounding values for printing.
+Consequently, the way to print rounded values is
+to specify the number of digits both as an
+argument to C<ffround> and in the C<%f> printf string,
+as follows:
+
+ printf "%.3f\n", $bigfloat->ffround(-3);
+
=head1 AUTHOR
Mark Biggar