1 # The following hash values are internally used:
2 # _e: exponent (BigInt)
3 # _m: mantissa (absolute BigInt)
4 # sign: +,-,"NaN" if not a number
7 # _f: flags, used to signal MBI not to touch our private parts
9 package Math::BigFloat;
14 use Math::BigInt qw/objectify/;
15 @ISA = qw( Exporter Math::BigInt);
18 use vars qw/$AUTOLOAD $accuracy $precision $div_scale $round_mode $rnd_mode/;
19 use vars qw/$upgrade $downgrade/;
20 my $class = "Math::BigFloat";
23 '<=>' => sub { $_[2] ?
24 ref($_[0])->bcmp($_[1],$_[0]) :
25 ref($_[0])->bcmp($_[0],$_[1])},
26 'int' => sub { $_[0]->as_number() }, # 'trunc' to bigint
27 'log' => sub { $_[0]->blog() },
30 ##############################################################################
31 # global constants, flags and accessory
33 use constant MB_NEVER_ROUND => 0x0001;
37 # constant for easier life
40 # class constants, use Class->constant_name() to access
41 $round_mode = 'even'; # one of 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'
49 ##############################################################################
50 # the old code had $rnd_mode, so we need to support it, too
53 sub TIESCALAR { my ($class) = @_; bless \$round_mode, $class; }
54 sub FETCH { return $round_mode; }
55 sub STORE { $rnd_mode = $_[0]->round_mode($_[1]); }
57 BEGIN { tie $rnd_mode, 'Math::BigFloat'; }
59 ##############################################################################
61 # in case we call SUPER::->foo() and this wants to call modify()
62 # sub modify () { 0; }
65 # valid method aliases for AUTOLOAD
66 my %methods = map { $_ => 1 }
67 qw / fadd fsub fmul fdiv fround ffround fsqrt fmod fstr fsstr fpow fnorm
68 fint facmp fcmp fzero fnan finf finc fdec flog ffac
69 fceil ffloor frsft flsft fone flog
71 # valid method's that can be hand-ed up (for AUTOLOAD)
72 my %hand_ups = map { $_ => 1 }
73 qw / is_nan is_inf is_negative is_positive
74 accuracy precision div_scale round_mode fneg fabs babs fnot
77 sub method_alias { return exists $methods{$_[0]||''}; }
78 sub method_hand_up { return exists $hand_ups{$_[0]||''}; }
81 ##############################################################################
86 # create a new BigFloat object from a string or another bigfloat object.
89 # sign => sign (+/-), or "NaN"
91 my ($class,$wanted,@r) = @_;
93 # avoid numify-calls by not using || on $wanted!
94 return $class->bzero() if !defined $wanted; # default to 0
95 return $wanted->copy() if UNIVERSAL::isa($wanted,'Math::BigFloat');
97 my $self = {}; bless $self, $class;
98 # shortcut for bigints and its subclasses
99 if ((ref($wanted)) && (ref($wanted) ne $class))
101 $self->{_m} = $wanted->as_number(); # get us a bigint copy
102 $self->{_e} = Math::BigInt->bzero();
104 $self->{sign} = $wanted->sign();
105 return $self->bnorm();
108 # handle '+inf', '-inf' first
109 if ($wanted =~ /^[+-]?inf$/)
111 $self->{_e} = Math::BigInt->bzero();
112 $self->{_m} = Math::BigInt->bzero();
113 $self->{sign} = $wanted;
114 $self->{sign} = '+inf' if $self->{sign} eq 'inf';
115 return $self->bnorm();
117 #print "new string '$wanted'\n";
118 my ($mis,$miv,$mfv,$es,$ev) = Math::BigInt::_split(\$wanted);
121 die "$wanted is not a number initialized to $class" if !$NaNOK;
122 $self->{_e} = Math::BigInt->bzero();
123 $self->{_m} = Math::BigInt->bzero();
124 $self->{sign} = $nan;
128 # make integer from mantissa by adjusting exp, then convert to bigint
129 # undef,undef to signal MBI that we don't need no bloody rounding
130 $self->{_e} = Math::BigInt->new("$$es$$ev",undef,undef); # exponent
131 $self->{_m} = Math::BigInt->new("$$miv$$mfv",undef,undef); # create mant.
132 # 3.123E0 = 3123E-3, and 3.123E-2 => 3123E-5
133 $self->{_e} -= CORE::length($$mfv) if CORE::length($$mfv) != 0;
134 $self->{sign} = $$mis;
136 # print "mbf new $self->{sign} $self->{_m} e $self->{_e}\n";
137 $self->bnorm()->round(@r); # first normalize, then round
142 # create a bigfloat 'NaN', if given a BigFloat, set it to 'NaN'
144 $self = $class if !defined $self;
147 my $c = $self; $self = {}; bless $self, $c;
149 $self->{_m} = Math::BigInt->bzero();
150 $self->{_e} = Math::BigInt->bzero();
151 $self->{sign} = $nan;
152 $self->{_a} = undef; $self->{_p} = undef;
158 # create a bigfloat '+-inf', if given a BigFloat, set it to '+-inf'
160 my $sign = shift; $sign = '+' if !defined $sign || $sign ne '-';
162 $self = $class if !defined $self;
165 my $c = $self; $self = {}; bless $self, $c;
167 $self->{_m} = Math::BigInt->bzero();
168 $self->{_e} = Math::BigInt->bzero();
169 $self->{sign} = $sign.'inf';
170 $self->{_a} = undef; $self->{_p} = undef;
176 # create a bigfloat '+-1', if given a BigFloat, set it to '+-1'
178 my $sign = shift; $sign = '+' if !defined $sign || $sign ne '-';
180 $self = $class if !defined $self;
183 my $c = $self; $self = {}; bless $self, $c;
185 $self->{_m} = Math::BigInt->bone();
186 $self->{_e} = Math::BigInt->bzero();
187 $self->{sign} = $sign;
191 if (defined $self->{_a} && defined $_[0] && $_[0] > $self->{_a});
193 if (defined $self->{_p} && defined $_[1] && $_[1] < $self->{_p});
200 # create a bigfloat '+0', if given a BigFloat, set it to 0
202 $self = $class if !defined $self;
205 my $c = $self; $self = {}; bless $self, $c;
207 $self->{_m} = Math::BigInt->bzero();
208 $self->{_e} = Math::BigInt->bone();
213 if (defined $self->{_a} && defined $_[0] && $_[0] > $self->{_a});
215 if (defined $self->{_p} && defined $_[1] && $_[1] < $self->{_p});
220 ##############################################################################
221 # string conversation
225 # (ref to BFLOAT or num_str ) return num_str
226 # Convert number from internal format to (non-scientific) string format.
227 # internal format is always normalized (no leading zeros, "-0" => "+0")
228 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
229 #my $x = shift; my $class = ref($x) || $x;
230 #$x = $class->new(shift) unless ref($x);
232 #die "Oups! e was $nan" if $x->{_e}->{sign} eq $nan;
233 #die "Oups! m was $nan" if $x->{_m}->{sign} eq $nan;
234 if ($x->{sign} !~ /^[+-]$/)
236 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
240 my $es = '0'; my $len = 1; my $cad = 0; my $dot = '.';
242 my $not_zero = !$x->is_zero();
245 $es = $x->{_m}->bstr();
246 $len = CORE::length($es);
247 if (!$x->{_e}->is_zero())
249 if ($x->{_e}->sign() eq '-')
252 if ($x->{_e} <= -$len)
254 # print "style: 0.xxxx\n";
255 my $r = $x->{_e}->copy(); $r->babs()->bsub( CORE::length($es) );
256 $es = '0.'. ('0' x $r) . $es; $cad = -($len+$r);
260 # print "insert '.' at $x->{_e} in '$es'\n";
261 substr($es,$x->{_e},0) = '.'; $cad = $x->{_e};
267 $es .= '0' x $x->{_e}; $len += $x->{_e}; $cad = 0;
271 $es = $x->{sign}.$es if $x->{sign} eq '-';
272 # if set accuracy or precision, pad with zeros
273 if ((defined $x->{_a}) && ($not_zero))
275 # 123400 => 6, 0.1234 => 4, 0.001234 => 4
276 my $zeros = $x->{_a} - $cad; # cad == 0 => 12340
277 $zeros = $x->{_a} - $len if $cad != $len;
278 $es .= $dot.'0' x $zeros if $zeros > 0;
280 elsif ($x->{_p} || 0 < 0)
282 # 123400 => 6, 0.1234 => 4, 0.001234 => 6
283 my $zeros = -$x->{_p} + $cad;
284 $es .= $dot.'0' x $zeros if $zeros > 0;
291 # (ref to BFLOAT or num_str ) return num_str
292 # Convert number from internal format to scientific string format.
293 # internal format is always normalized (no leading zeros, "-0E0" => "+0E0")
294 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
295 #my $x = shift; my $class = ref($x) || $x;
296 #$x = $class->new(shift) unless ref($x);
298 #die "Oups! e was $nan" if $x->{_e}->{sign} eq $nan;
299 #die "Oups! m was $nan" if $x->{_m}->{sign} eq $nan;
300 if ($x->{sign} !~ /^[+-]$/)
302 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
305 my $sign = $x->{_e}->{sign}; $sign = '' if $sign eq '-';
307 return $x->{_m}->bstr().$sep.$x->{_e}->bstr();
312 # Make a number from a BigFloat object
313 # simple return string and let Perl's atoi()/atof() handle the rest
314 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
318 ##############################################################################
319 # public stuff (usually prefixed with "b")
322 # todo: this must be overwritten and return NaN for non-integer values
323 # band(), bior(), bxor(), too
326 # $class->SUPER::bnot($class,@_);
331 # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
332 # (BFLOAT or num_str, BFLOAT or num_str) return cond_code
333 my ($self,$x,$y) = objectify(2,@_);
335 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
337 # handle +-inf and NaN
338 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
339 return 0 if ($x->{sign} eq $y->{sign}) && ($x->{sign} =~ /^[+-]inf$/);
340 return +1 if $x->{sign} eq '+inf';
341 return -1 if $x->{sign} eq '-inf';
342 return -1 if $y->{sign} eq '+inf';
346 # check sign for speed first
347 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
348 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
351 my $xz = $x->is_zero();
352 my $yz = $y->is_zero();
353 return 0 if $xz && $yz; # 0 <=> 0
354 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
355 return 1 if $yz && $x->{sign} eq '+'; # +x <=> 0
357 # adjust so that exponents are equal
358 my $lxm = $x->{_m}->length();
359 my $lym = $y->{_m}->length();
360 my $lx = $lxm + $x->{_e};
361 my $ly = $lym + $y->{_e};
362 my $l = $lx - $ly; $l->bneg() if $x->{sign} eq '-';
363 return $l <=> 0 if $l != 0;
365 # lengths (corrected by exponent) are equal
366 # so make mantissa euqal length by padding with zero (shift left)
367 my $diff = $lxm - $lym;
368 my $xm = $x->{_m}; # not yet copy it
372 $ym = $y->{_m}->copy()->blsft($diff,10);
376 $xm = $x->{_m}->copy()->blsft(-$diff,10);
378 my $rc = $xm->bcmp($ym);
379 $rc = -$rc if $x->{sign} eq '-'; # -124 < -123
385 # Compares 2 values, ignoring their signs.
386 # Returns one of undef, <0, =0, >0. (suitable for sort)
387 # (BFLOAT or num_str, BFLOAT or num_str) return cond_code
388 my ($self,$x,$y) = objectify(2,@_);
390 # handle +-inf and NaN's
391 if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/)
393 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
394 return 0 if ($x->is_inf() && $y->is_inf());
395 return 1 if ($x->is_inf() && !$y->is_inf());
400 my $xz = $x->is_zero();
401 my $yz = $y->is_zero();
402 return 0 if $xz && $yz; # 0 <=> 0
403 return -1 if $xz && !$yz; # 0 <=> +y
404 return 1 if $yz && !$xz; # +x <=> 0
406 # adjust so that exponents are equal
407 my $lxm = $x->{_m}->length();
408 my $lym = $y->{_m}->length();
409 my $lx = $lxm + $x->{_e};
410 my $ly = $lym + $y->{_e};
412 return $l <=> 0 if $l != 0;
414 # lengths (corrected by exponent) are equal
415 # so make mantissa equal-length by padding with zero (shift left)
416 my $diff = $lxm - $lym;
417 my $xm = $x->{_m}; # not yet copy it
421 $ym = $y->{_m}->copy()->blsft($diff,10);
425 $xm = $x->{_m}->copy()->blsft(-$diff,10);
427 $xm->bcmp($ym) <=> 0;
432 # add second arg (BFLOAT or string) to first (BFLOAT) (modifies first)
433 # return result as BFLOAT
434 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
436 #print "mbf badd $x $y\n";
437 # inf and NaN handling
438 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
441 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
443 if (($x->{sign} =~ /^[+-]inf$/) && ($y->{sign} =~ /^[+-]inf$/))
445 # + and + => +, - and - => -, + and - => 0, - and + => 0
446 return $x->bzero() if $x->{sign} ne $y->{sign};
449 # +-inf + something => +inf
450 # something +-inf => +-inf
451 $x->{sign} = $y->{sign}, return $x if $y->{sign} =~ /^[+-]inf$/;
455 # speed: no add for 0+y or x+0
456 return $x if $y->is_zero(); # x+0
457 if ($x->is_zero()) # 0+y
459 # make copy, clobbering up x (modify in place!)
460 $x->{_e} = $y->{_e}->copy();
461 $x->{_m} = $y->{_m}->copy();
462 $x->{sign} = $y->{sign} || $nan;
463 return $x->round($a,$p,$r,$y);
466 # take lower of the two e's and adapt m1 to it to match m2
467 my $e = $y->{_e}; $e = Math::BigInt::bzero() if !defined $e; # if no BFLOAT
469 my $add = $y->{_m}->copy();
472 my $e1 = $e->copy()->babs();
473 $x->{_m} *= (10 ** $e1);
474 $x->{_e} += $e; # need the sign of e
480 # else: both e are the same, so just leave them
481 $x->{_m}->{sign} = $x->{sign}; # fiddle with signs
482 $add->{sign} = $y->{sign};
483 $x->{_m} += $add; # finally do add/sub
484 $x->{sign} = $x->{_m}->{sign}; # re-adjust signs
485 $x->{_m}->{sign} = '+'; # mantissa always positiv
486 # delete trailing zeros, then round
487 return $x->bnorm()->round($a,$p,$r,$y);
492 # (BigFloat or num_str, BigFloat or num_str) return BigFloat
493 # subtract second arg from first, modify first
494 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
496 if (!$y->is_zero()) # don't need to do anything if $y is 0
498 $y->{sign} =~ tr/+\-/-+/; # does nothing for NaN
499 $x->badd($y,$a,$p,$r); # badd does not leave internal zeros
500 $y->{sign} =~ tr/+\-/-+/; # refix $y (does nothing for NaN)
502 $x; # already rounded by badd()
507 # increment arg by one
508 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
510 if ($x->{_e}->sign() eq '-')
512 return $x->badd($self->bone(),$a,$p,$r); # digits after dot
515 if (!$x->{_e}->is_zero())
517 $x->{_m}->blsft($x->{_e},10); # 1e2 => 100
521 if ($x->{sign} eq '+')
524 return $x->bnorm()->bround($a,$p,$r);
526 elsif ($x->{sign} eq '-')
529 $x->{sign} = '+' if $x->{_m}->is_zero(); # -1 +1 => -0 => +0
530 return $x->bnorm()->bround($a,$p,$r);
532 # inf, nan handling etc
533 $x->badd($self->__one(),$a,$p,$r); # does round
538 # decrement arg by one
539 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
541 if ($x->{_e}->sign() eq '-')
543 return $x->badd($self->bone('-'),$a,$p,$r); # digits after dot
546 if (!$x->{_e}->is_zero())
548 $x->{_m}->blsft($x->{_e},10); # 1e2 => 100
552 my $zero = $x->is_zero();
554 if (($x->{sign} eq '-') || $zero)
557 $x->{sign} = '-' if $zero; # 0 => 1 => -1
558 $x->{sign} = '+' if $x->{_m}->is_zero(); # -1 +1 => -0 => +0
559 return $x->bnorm()->round($a,$p,$r);
562 elsif ($x->{sign} eq '+')
565 return $x->bnorm()->round($a,$p,$r);
567 # inf, nan handling etc
568 $x->badd($self->bone('-'),$a,$p,$r); # does round
573 my ($self,$x,$base,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(2,@_);
575 # http://www.efunda.com/math/taylor_series/logarithmic.cfm?search_string=log
579 # taylor: | u 1 u^3 1 u^5 |
580 # ln (x) = 2 | --- + - * --- + - * --- + ... | x > 0
581 # |_ v 3 v^3 5 v^5 _|
583 # we need to limit the accuracy to protect against overflow
586 my @params = $x->_find_round_parameters($a,$p,$r);
588 # no rounding at all, so must use fallback
589 if (scalar @params == 1)
591 # simulate old behaviour
592 $params[1] = $self->div_scale(); # and round to it as accuracy
593 $scale = $params[1]+4; # at least four more for proper round
594 $params[3] = $r; # round mode by caller or undef
595 $fallback = 1; # to clear a/p afterwards
599 # the 4 below is empirical, and there might be cases where it is not
601 $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined
604 return $x->bzero(@params) if $x->is_one();
605 return $x->bnan() if $x->{sign} ne '+' || $x->is_zero();
606 #return $x->bone('+',@params) if $x->bcmp($base) == 0;
608 # when user set globals, they would interfere with our calculation, so
609 # disable then and later re-enable them
611 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
612 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
613 # we also need to disable any set A or P on $x (_find_round_parameters took
614 # them already into account), since these would interfere, too
615 delete $x->{_a}; delete $x->{_p};
616 # need to disable $upgrade in BigInt, to aoid deep recursion
617 local $Math::BigInt::upgrade = undef;
619 my $v = $x->copy(); $v->binc(); # v = x+1
620 $x->bdec(); my $u = $x->copy(); # u = x-1; x = x-1
622 $x->bdiv($v,$scale); # first term: u/v
624 my $below = $v->copy();
625 my $over = $u->copy();
626 $u *= $u; $v *= $v; # u^2, v^2
627 $below->bmul($v); # u^3, v^3
629 my $factor = $self->new(3); my $two = $self->new(2);
631 my $diff = $self->bone();
632 my $limit = $self->new("1E-". ($scale-1)); my $last;
633 # print "diff $diff limit $limit\n";
634 while ($diff->bcmp($limit) > 0)
636 #print "$x $over $below $factor\n";
637 $diff = $x->copy()->bsub($last)->babs();
638 #print "diff $diff $limit\n";
640 $x += $over->copy()->bdiv($below->copy()->bmul($factor),$scale);
641 $over *= $u; $below *= $v; $factor->badd($two);
645 # shortcut to not run trough _find_round_parameters again
646 if (defined $params[1])
648 $x->bround($params[1],$params[3]); # then round accordingly
652 $x->bfround($params[2],$params[3]); # then round accordingly
656 # clear a/p after round, since user did not request it
657 $x->{_a} = undef; $x->{_p} = undef;
660 $$abr = $ab; $$pbr = $pb;
667 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
668 # does not modify arguments, but returns new object
669 # Lowest Common Multiplicator
671 my ($self,@arg) = objectify(0,@_);
672 my $x = $self->new(shift @arg);
673 while (@arg) { $x = _lcm($x,shift @arg); }
679 # (BFLOAT or num_str, BFLOAT or num_str) return BINT
680 # does not modify arguments, but returns new object
681 # GCD -- Euclids algorithm Knuth Vol 2 pg 296
683 my ($self,@arg) = objectify(0,@_);
684 my $x = $self->new(shift @arg);
685 while (@arg) { $x = _gcd($x,shift @arg); }
689 ###############################################################################
690 # is_foo methods (is_negative, is_positive are inherited from BigInt)
694 # return true if arg (BFLOAT or num_str) is an integer
695 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
697 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
698 $x->{_e}->{sign} eq '+'; # 1e-1 => no integer
704 # return true if arg (BFLOAT or num_str) is zero
705 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
707 return 1 if $x->{sign} eq '+' && $x->{_m}->is_zero();
713 # return true if arg (BFLOAT or num_str) is +1 or -1 if signis given
714 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
716 my $sign = shift || ''; $sign = '+' if $sign ne '-';
718 if ($x->{sign} eq $sign && $x->{_e}->is_zero() && $x->{_m}->is_one());
724 # return true if arg (BFLOAT or num_str) is odd or false if even
725 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
727 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
728 ($x->{_e}->is_zero() && $x->{_m}->is_odd());
734 # return true if arg (BINT or num_str) is even or false if odd
735 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
737 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
738 # return 1 if $x->{_m}->is_zero(); # 0e1 is even
739 return 1 if ($x->{_e}->{sign} eq '+' # 123.45 is never
740 && $x->{_m}->is_even()); # but 1200 is
746 # multiply two numbers -- stolen from Knuth Vol 2 pg 233
747 # (BINT or num_str, BINT or num_str) return BINT
748 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
750 # print "mbf bmul $x->{_m}e$x->{_e} $y->{_m}e$y->{_e}\n";
751 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
754 return $x->bzero() if $x->is_zero() || $y->is_zero();
756 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
758 # result will always be +-inf:
759 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
760 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
761 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
762 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
763 return $x->binf('-');
766 # aEb * cEd = (a*c)E(b+d)
767 $x->{_m}->bmul($y->{_m});
768 $x->{_e}->badd($y->{_e});
770 $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
771 return $x->bnorm()->round($a,$p,$r,$y);
776 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return
777 # (BFLOAT,BFLOAT) (quo,rem) or BINT (only rem)
778 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
780 # x / +-inf => 0, reminder x
781 return wantarray ? ($x->bzero(),$x->copy()) : $x->bzero()
782 if $y->{sign} =~ /^[+-]inf$/;
784 # NaN if x == NaN or y == NaN or x==y==0
785 return wantarray ? ($x->bnan(),bnan()) : $x->bnan()
786 if (($x->is_nan() || $y->is_nan()) ||
787 ($x->is_zero() && $y->is_zero()));
789 # 5 / 0 => +inf, -6 / 0 => -inf
791 ? ($x->binf($x->{sign}),$self->bnan()) : $x->binf($x->{sign})
792 if ($x->{sign} =~ /^[+-]$/ && $y->is_zero());
794 # x== 0 or y == 1 or y == -1
795 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
797 # we need to limit the accuracy to protect against overflow
800 my @params = $x->_find_round_parameters($a,$p,$r,$y);
802 # no rounding at all, so must use fallback
803 if (scalar @params == 1)
805 # simulate old behaviour
806 $params[1] = $self->div_scale(); # and round to it as accuracy
807 $scale = $params[1]+4; # at least four more for proper round
808 $params[3] = $r; # round mode by caller or undef
809 $fallback = 1; # to clear a/p afterwards
813 # the 4 below is empirical, and there might be cases where it is not
815 $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined
817 my $lx = $x->{_m}->length(); my $ly = $y->{_m}->length();
818 $scale = $lx if $lx > $scale;
819 $scale = $ly if $ly > $scale;
820 my $diff = $ly - $lx;
821 $scale += $diff if $diff > 0; # if lx << ly, but not if ly << lx!
823 # make copy of $x in case of list context for later reminder calculation
825 if (wantarray && !$y->is_one())
830 $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
832 # check for / +-1 ( +/- 1E0)
835 # promote BigInts and it's subclasses (except when already a BigFloat)
836 $y = $self->new($y) unless $y->isa('Math::BigFloat');
838 # calculate the result to $scale digits and then round it
839 # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
840 $x->{_m}->blsft($scale,10);
841 $x->{_m}->bdiv( $y->{_m} ); # a/c
842 $x->{_e}->bsub( $y->{_e} ); # b-d
843 $x->{_e}->bsub($scale); # correct for 10**scale
844 $x->bnorm(); # remove trailing 0's
847 # shortcut to not run trough _find_round_parameters again
848 if (defined $params[1])
850 $x->bround($params[1],$params[3]); # then round accordingly
854 $x->bfround($params[2],$params[3]); # then round accordingly
858 # clear a/p after round, since user did not request it
859 $x->{_a} = undef; $x->{_p} = undef;
866 $rem->bmod($y,$params[1],$params[2],$params[3]); # copy already done
870 $rem = $self->bzero();
874 # clear a/p after round, since user did not request it
875 $rem->{_a} = undef; $rem->{_p} = undef;
884 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return reminder
885 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
887 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
889 my ($d,$re) = $self->SUPER::_div_inf($x,$y);
890 return $re->round($a,$p,$r,$y);
892 return $x->bnan() if $x->is_zero() && $y->is_zero();
893 return $x if $y->is_zero();
894 return $x->bnan() if $x->is_nan() || $y->is_nan();
895 return $x->bzero() if $y->is_one() || $x->is_zero();
897 # inf handling is missing here
899 my $cmp = $x->bacmp($y); # equal or $x < $y?
900 return $x->bzero($a,$p) if $cmp == 0; # $x == $y => result 0
902 # only $y of the operands negative?
903 my $neg = 0; $neg = 1 if $x->{sign} ne $y->{sign};
905 $x->{sign} = $y->{sign}; # calc sign first
906 return $x->round($a,$p,$r) if $cmp < 0 && $neg == 0; # $x < $y => result $x
908 my $ym = $y->{_m}->copy();
911 $ym->blsft($y->{_e},10) if $y->{_e}->{sign} eq '+' && !$y->{_e}->is_zero();
913 # if $y has digits after dot
914 my $shifty = 0; # correct _e of $x by this
915 if ($y->{_e}->{sign} eq '-') # has digits after dot
917 # 123 % 2.5 => 1230 % 25 => 5 => 0.5
918 $shifty = $y->{_e}->copy()->babs(); # no more digits after dot
919 $x->blsft($shifty,10); # 123 => 1230, $y->{_m} is already 25
921 # $ym is now mantissa of $y based on exponent 0
923 my $shiftx = 0; # correct _e of $x by this
924 if ($x->{_e}->{sign} eq '-') # has digits after dot
926 # 123.4 % 20 => 1234 % 200
927 $shiftx = $x->{_e}->copy()->babs(); # no more digits after dot
928 $ym->blsft($shiftx,10);
930 # 123e1 % 20 => 1230 % 20
931 if ($x->{_e}->{sign} eq '+' && !$x->{_e}->is_zero())
933 $x->{_m}->blsft($x->{_e},10);
935 $x->{_e} = Math::BigInt->bzero() unless $x->{_e}->is_zero();
937 $x->{_e}->bsub($shiftx) if $shiftx != 0;
938 $x->{_e}->bsub($shifty) if $shifty != 0;
940 # now mantissas are equalized, exponent of $x is adjusted, so calc result
941 # $ym->{sign} = '-' if $neg; # bmod() will make the correction for us
945 $x->{sign} = '+' if $x->{_m}->is_zero(); # fix sign for -0
948 if ($neg != 0) # one of them negative => correct in place
953 $x->{sign} = '+' if $x->{_m}->is_zero(); # fix sign for -0
957 $x->round($a,$p,$r,$y); # round and return
962 # calculate square root; this should probably
963 # use a different test to see whether the accuracy we want is...
964 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
966 return $x->bnan() if $x->{sign} eq 'NaN' || $x->{sign} =~ /^-/; # <0, NaN
967 return $x if $x->{sign} eq '+inf'; # +inf
968 return $x if $x->is_zero() || $x->is_one();
970 # we need to limit the accuracy to protect against overflow
973 my @params = $x->_find_round_parameters($a,$p,$r);
975 # no rounding at all, so must use fallback
976 if (scalar @params == 1)
978 # simulate old behaviour
979 $params[1] = $self->div_scale(); # and round to it as accuracy
980 $scale = $params[1]+4; # at least four more for proper round
981 $params[3] = $r; # round mode by caller or undef
982 $fallback = 1; # to clear a/p afterwards
986 # the 4 below is empirical, and there might be cases where it is not
988 $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined
991 # when user set globals, they would interfere with our calculation, so
992 # disable then and later re-enable them
994 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
995 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
996 # we also need to disable any set A or P on $x (_find_round_parameters took
997 # them already into account), since these would interfere, too
998 delete $x->{_a}; delete $x->{_p};
999 # need to disable $upgrade in BigInt, to aoid deep recursion
1000 local $Math::BigInt::upgrade = undef;
1002 my $xas = $x->as_number();
1003 my $gs = $xas->copy()->bsqrt(); # some guess
1005 if (($x->{_e}->{sign} ne '-') # guess can't be accurate if there are
1006 # digits after the dot
1007 && ($xas->bacmp($gs * $gs) == 0)) # guess hit the nail on the head?
1010 $x->{_m} = $gs; $x->{_e} = Math::BigInt->bzero(); $x->bnorm();
1011 # shortcut to not run trough _find_round_parameters again
1012 if (defined $params[1])
1014 $x->bround($params[1],$params[3]); # then round accordingly
1018 $x->bfround($params[2],$params[3]); # then round accordingly
1022 # clear a/p after round, since user did not request it
1023 $x->{_a} = undef; $x->{_p} = undef;
1025 ${"$self\::accuracy"} = $ab; ${"$self\::precision"} = $pb;
1028 $gs = $self->new( $gs ); # BigInt to BigFloat
1030 my $lx = $x->{_m}->length();
1031 $scale = $lx if $scale < $lx;
1032 my $e = $self->new("1E-$scale"); # make test variable
1033 # return $x->bnan() if $e->sign() eq 'NaN';
1036 my $two = $self->new(2);
1038 # promote BigInts and it's subclasses (except when already a BigFloat)
1039 $y = $self->new($y) unless $y->isa('Math::BigFloat');
1044 $rem = $y->copy()->bdiv($gs,$scale)->badd($gs)->bdiv($two,$scale);
1045 $diff = $rem->copy()->bsub($gs)->babs();
1048 # copy over to modify $x
1049 $x->{_m} = $rem->{_m}; $x->{_e} = $rem->{_e};
1051 # shortcut to not run trough _find_round_parameters again
1052 if (defined $params[1])
1054 $x->bround($params[1],$params[3]); # then round accordingly
1058 $x->bfround($params[2],$params[3]); # then round accordingly
1062 # clear a/p after round, since user did not request it
1063 $x->{_a} = undef; $x->{_p} = undef;
1066 $$abr = $ab; $$pbr = $pb;
1072 # (BINT or num_str, BINT or num_str) return BINT
1073 # compute factorial numbers
1074 # modifies first argument
1075 my ($self,$x,@r) = objectify(1,@_);
1077 return $x->bnan() if $x->{sign} ne '+'; # inf, NnN, <0 etc => NaN
1078 return $x->bone(@r) if $x->is_zero() || $x->is_one(); # 0 or 1 => 1
1080 return $x->bnan() if $x->{_e}->{sign} ne '+'; # digits after dot?
1082 # use BigInt's bfac() for faster calc
1083 $x->{_m}->blsft($x->{_e},10); # un-norm m
1084 $x->{_e}->bzero(); # norm $x again
1085 $x->{_m}->bfac(); # factorial
1088 #my $n = $x->copy();
1090 #my $f = $self->new(2);
1091 #while ($f->bacmp($n) < 0)
1093 # $x->bmul($f); $f->binc();
1095 #$x->bmul($f); # last step
1096 $x->round(@r); # round
1101 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
1102 # compute power of two numbers, second arg is used as integer
1103 # modifies first argument
1105 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
1107 return $x if $x->{sign} =~ /^[+-]inf$/;
1108 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
1109 return $x->bone() if $y->is_zero();
1110 return $x if $x->is_one() || $y->is_one();
1111 my $y1 = $y->as_number(); # make bigint (trunc)
1113 if ($x->{sign} eq '-' && $x->{_m}->is_one() && $x->{_e}->is_zero())
1115 # if $x == -1 and odd/even y => +1/-1 because +-1 ^ (+-1) => +-1
1116 return $y1->is_odd() ? $x : $x->babs(1);
1118 return $x if $x->is_zero() && $y->{sign} eq '+'; # 0**y => 0 (if not y <= 0)
1119 # 0 ** -y => 1 / (0 ** y) => / 0! (1 / 0 => +inf)
1120 return $x->binf() if $x->is_zero() && $y->{sign} eq '-';
1122 # calculate $x->{_m} ** $y and $x->{_e} * $y separately (faster)
1124 $x->{_m}->bpow($y1);
1125 $x->{_e}->bmul($y1);
1126 $x->{sign} = $nan if $x->{_m}->{sign} eq $nan || $x->{_e}->{sign} eq $nan;
1128 if ($y->{sign} eq '-')
1130 # modify $x in place!
1131 my $z = $x->copy(); $x->bzero()->binc();
1132 return $x->bdiv($z,$a,$p,$r); # round in one go (might ignore y's A!)
1134 return $x->round($a,$p,$r,$y);
1137 ###############################################################################
1138 # rounding functions
1142 # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
1143 # $n == 0 means round to integer
1144 # expects and returns normalized numbers!
1145 my $x = shift; my $self = ref($x) || $x; $x = $self->new(shift) if !ref($x);
1147 return $x if $x->modify('bfround');
1149 my ($scale,$mode) = $x->_scale_p($self->precision(),$self->round_mode(),@_);
1150 return $x if !defined $scale; # no-op
1152 # never round a 0, +-inf, NaN
1155 $x->{_p} = $scale if !defined $x->{_p} || $x->{_p} < $scale; # -3 < -2
1158 return $x if $x->{sign} !~ /^[+-]$/;
1159 # print "MBF bfround $x to scale $scale mode $mode\n";
1161 # don't round if x already has lower precision
1162 return $x if (defined $x->{_p} && $x->{_p} < 0 && $scale < $x->{_p});
1164 $x->{_p} = $scale; # remember round in any case
1165 $x->{_a} = undef; # and clear A
1168 # print "bfround scale $scale e $x->{_e}\n";
1169 # round right from the '.'
1170 return $x if $x->{_e} >= 0; # nothing to round
1171 $scale = -$scale; # positive for simplicity
1172 my $len = $x->{_m}->length(); # length of mantissa
1173 my $dad = -$x->{_e}; # digits after dot
1174 my $zad = 0; # zeros after dot
1175 $zad = -$len-$x->{_e} if ($x->{_e} < -$len);# for 0.00..00xxx style
1176 #print "scale $scale dad $dad zad $zad len $len\n";
1178 # number bsstr len zad dad
1179 # 0.123 123e-3 3 0 3
1180 # 0.0123 123e-4 3 1 4
1183 # 1.2345 12345e-4 5 0 4
1185 # do not round after/right of the $dad
1186 return $x if $scale > $dad; # 0.123, scale >= 3 => exit
1188 # round to zero if rounding inside the $zad, but not for last zero like:
1189 # 0.0065, scale -2, round last '0' with following '65' (scale == zad case)
1190 return $x->bzero() if $scale < $zad;
1191 if ($scale == $zad) # for 0.006, scale -3 and trunc
1197 # adjust round-point to be inside mantissa
1200 $scale = $scale-$zad;
1204 my $dbd = $len - $dad; $dbd = 0 if $dbd < 0; # digits before dot
1205 $scale = $dbd+$scale;
1208 # print "round to $x->{_m} to $scale\n";
1212 # 123 => 100 means length(123) = 3 - $scale (2) => 1
1214 my $dbt = $x->{_m}->length();
1216 my $dbd = $dbt + $x->{_e};
1217 # should be the same, so treat it as this
1218 $scale = 1 if $scale == 0;
1219 # shortcut if already integer
1220 return $x if $scale == 1 && $dbt <= $dbd;
1221 # maximum digits before dot
1226 # not enough digits before dot, so round to zero
1229 elsif ( $scale == $dbd )
1236 $scale = $dbd - $scale;
1240 # print "using $scale for $x->{_m} with '$mode'\n";
1241 # pass sign to bround for rounding modes '+inf' and '-inf'
1242 $x->{_m}->{sign} = $x->{sign};
1243 $x->{_m}->bround($scale,$mode);
1244 $x->{_m}->{sign} = '+'; # fix sign back
1250 # accuracy: preserve $N digits, and overwrite the rest with 0's
1251 my $x = shift; my $self = ref($x) || $x; $x = $self->new(shift) if !ref($x);
1253 die ('bround() needs positive accuracy') if ($_[0] || 0) < 0;
1255 my ($scale,$mode) = $x->_scale_a($self->accuracy(),$self->round_mode(),@_);
1256 return $x if !defined $scale; # no-op
1258 return $x if $x->modify('bround');
1260 # scale is now either $x->{_a}, $accuracy, or the user parameter
1261 # test whether $x already has lower accuracy, do nothing in this case
1262 # but do round if the accuracy is the same, since a math operation might
1263 # want to round a number with A=5 to 5 digits afterwards again
1264 return $x if defined $_[0] && defined $x->{_a} && $x->{_a} < $_[0];
1266 # scale < 0 makes no sense
1267 # never round a +-inf, NaN
1268 return $x if ($scale < 0) || $x->{sign} !~ /^[+-]$/;
1270 # 1: $scale == 0 => keep all digits
1271 # 2: never round a 0
1272 # 3: if we should keep more digits than the mantissa has, do nothing
1273 if ($scale == 0 || $x->is_zero() || $x->{_m}->length() <= $scale)
1275 $x->{_a} = $scale if !defined $x->{_a} || $x->{_a} > $scale;
1279 # pass sign to bround for '+inf' and '-inf' rounding modes
1280 $x->{_m}->{sign} = $x->{sign};
1281 $x->{_m}->bround($scale,$mode); # round mantissa
1282 $x->{_m}->{sign} = '+'; # fix sign back
1283 # $x->{_m}->{_a} = undef; $x->{_m}->{_p} = undef;
1284 $x->{_a} = $scale; # remember rounding
1285 $x->{_p} = undef; # and clear P
1286 $x->bnorm(); # del trailing zeros gen. by bround()
1291 # return integer less or equal then $x
1292 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1294 return $x if $x->modify('bfloor');
1296 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1298 # if $x has digits after dot
1299 if ($x->{_e}->{sign} eq '-')
1301 $x->{_m}->brsft(-$x->{_e},10);
1303 $x-- if $x->{sign} eq '-';
1305 $x->round($a,$p,$r);
1310 # return integer greater or equal then $x
1311 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1313 return $x if $x->modify('bceil');
1314 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1316 # if $x has digits after dot
1317 if ($x->{_e}->{sign} eq '-')
1319 $x->{_m}->brsft(-$x->{_e},10);
1321 $x++ if $x->{sign} eq '+';
1323 $x->round($a,$p,$r);
1328 # shift right by $y (divide by power of 2)
1329 my ($self,$x,$y,$n,$a,$p,$r) = objectify(2,@_);
1331 return $x if $x->modify('brsft');
1332 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1334 $n = 2 if !defined $n; $n = Math::BigFloat->new($n);
1335 $x->bdiv($n ** $y,$a,$p,$r,$y);
1340 # shift right by $y (divide by power of 2)
1341 my ($self,$x,$y,$n,$a,$p,$r) = objectify(2,@_);
1343 return $x if $x->modify('brsft');
1344 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1346 $n = 2 if !defined $n; $n = Math::BigFloat->new($n);
1347 $x->bmul($n ** $y,$a,$p,$r,$y);
1350 ###############################################################################
1354 # going through AUTOLOAD for every DESTROY is costly, so avoid it by empty sub
1359 # make fxxx and bxxx both work by selectively mapping fxxx() to MBF::bxxx()
1360 # or falling back to MBI::bxxx()
1361 my $name = $AUTOLOAD;
1363 $name =~ s/.*:://; # split package
1365 if (!method_alias($name))
1369 # delayed load of Carp and avoid recursion
1371 Carp::croak ("Can't call a method without name");
1373 if (!method_hand_up($name))
1375 # delayed load of Carp and avoid recursion
1377 Carp::croak ("Can't call $class\-\>$name, not a valid method");
1379 # try one level up, but subst. bxxx() for fxxx() since MBI only got bxxx()
1381 return &{'Math::BigInt'."::$name"}(@_);
1383 my $bname = $name; $bname =~ s/^f/b/;
1384 *{$class."::$name"} = \&$bname;
1390 # return a copy of the exponent
1391 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1393 if ($x->{sign} !~ /^[+-]$/)
1395 my $s = $x->{sign}; $s =~ s/^[+-]//;
1396 return $self->new($s); # -inf, +inf => +inf
1398 return $x->{_e}->copy();
1403 # return a copy of the mantissa
1404 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1406 if ($x->{sign} !~ /^[+-]$/)
1408 my $s = $x->{sign}; $s =~ s/^[+]//;
1409 return $self->new($s); # -inf, +inf => +inf
1411 my $m = $x->{_m}->copy(); # faster than going via bstr()
1412 $m->bneg() if $x->{sign} eq '-';
1419 # return a copy of both the exponent and the mantissa
1420 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1422 if ($x->{sign} !~ /^[+-]$/)
1424 my $s = $x->{sign}; $s =~ s/^[+]//; my $se = $s; $se =~ s/^[-]//;
1425 return ($self->new($s),$self->new($se)); # +inf => inf and -inf,+inf => inf
1427 my $m = $x->{_m}->copy(); # faster than going via bstr()
1428 $m->bneg() if $x->{sign} eq '-';
1429 return ($m,$x->{_e}->copy());
1432 ##############################################################################
1433 # private stuff (internal use only)
1438 my $l = scalar @_; my $j = 0; my @a = @_;
1439 for ( my $i = 0; $i < $l ; $i++, $j++)
1441 if ( $_[$i] eq ':constant' )
1443 # this rest causes overlord er load to step in
1444 # print "overload @_\n";
1445 overload::constant float => sub { $self->new(shift); };
1446 splice @a, $j, 1; $j--;
1448 elsif ($_[$i] eq 'upgrade')
1450 # this causes upgrading
1451 $upgrade = $_[$i+1]; # or undef to disable
1452 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
1453 splice @a, $j, $s; $j -= $s;
1456 # any non :constant stuff is handled by our parent, Exporter
1457 # even if @_ is empty, to give it a chance
1458 $self->SUPER::import(@a); # for subclasses
1459 $self->export_to_level(1,$self,@a); # need this, too
1464 # adjust m and e so that m is smallest possible
1465 # round number according to accuracy and precision settings
1466 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1468 return $x if $x->{sign} !~ /^[+-]$/; # inf, nan etc
1470 my $zeros = $x->{_m}->_trailing_zeros(); # correct for trailing zeros
1473 $x->{_m}->brsft($zeros,10); $x->{_e} += $zeros;
1475 # for something like 0Ey, set y to 1, and -0 => +0
1476 $x->{sign} = '+', $x->{_e}->bone() if $x->{_m}->is_zero();
1477 # this is to prevent automatically rounding when MBI's globals are set
1478 $x->{_m}->{_f} = MB_NEVER_ROUND;
1479 $x->{_e}->{_f} = MB_NEVER_ROUND;
1480 # 'forget' that mantissa was rounded via MBI::bround() in MBF's bfround()
1481 $x->{_m}->{_a} = undef; $x->{_e}->{_a} = undef;
1482 $x->{_m}->{_p} = undef; $x->{_e}->{_p} = undef;
1483 $x; # MBI bnorm is no-op, so dont call it
1486 ##############################################################################
1487 # internal calculation routines
1491 # return copy as a bigint representation of this BigFloat number
1492 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1495 if ($x->{_e}->is_zero())
1497 $z = $x->{_m}->copy();
1498 $z->{sign} = $x->{sign};
1501 $z = $x->{_m}->copy();
1504 $z->brsft(-$x->{_e},10);
1508 $z->blsft($x->{_e},10);
1510 $z->{sign} = $x->{sign};
1517 my $class = ref($x) || $x;
1518 $x = $class->new(shift) unless ref($x);
1520 return 1 if $x->{_m}->is_zero();
1521 my $len = $x->{_m}->length();
1522 $len += $x->{_e} if $x->{_e}->sign() eq '+';
1525 my $t = Math::BigInt::bzero();
1526 $t = $x->{_e}->copy()->babs() if $x->{_e}->sign() eq '-';
1537 Math::BigFloat - Arbitrary size floating point math package
1544 $x = Math::BigFloat->new($str); # defaults to 0
1545 $nan = Math::BigFloat->bnan(); # create a NotANumber
1546 $zero = Math::BigFloat->bzero(); # create a +0
1547 $inf = Math::BigFloat->binf(); # create a +inf
1548 $inf = Math::BigFloat->binf('-'); # create a -inf
1549 $one = Math::BigFloat->bone(); # create a +1
1550 $one = Math::BigFloat->bone('-'); # create a -1
1553 $x->is_zero(); # true if arg is +0
1554 $x->is_nan(); # true if arg is NaN
1555 $x->is_one(); # true if arg is +1
1556 $x->is_one('-'); # true if arg is -1
1557 $x->is_odd(); # true if odd, false for even
1558 $x->is_even(); # true if even, false for odd
1559 $x->is_positive(); # true if >= 0
1560 $x->is_negative(); # true if < 0
1561 $x->is_inf(sign); # true if +inf, or -inf (default is '+')
1563 $x->bcmp($y); # compare numbers (undef,<0,=0,>0)
1564 $x->bacmp($y); # compare absolutely (undef,<0,=0,>0)
1565 $x->sign(); # return the sign, either +,- or NaN
1566 $x->digit($n); # return the nth digit, counting from right
1567 $x->digit(-$n); # return the nth digit, counting from left
1569 # The following all modify their first argument:
1572 $x->bzero(); # set $i to 0
1573 $x->bnan(); # set $i to NaN
1574 $x->bone(); # set $x to +1
1575 $x->bone('-'); # set $x to -1
1576 $x->binf(); # set $x to inf
1577 $x->binf('-'); # set $x to -inf
1579 $x->bneg(); # negation
1580 $x->babs(); # absolute value
1581 $x->bnorm(); # normalize (no-op)
1582 $x->bnot(); # two's complement (bit wise not)
1583 $x->binc(); # increment x by 1
1584 $x->bdec(); # decrement x by 1
1586 $x->badd($y); # addition (add $y to $x)
1587 $x->bsub($y); # subtraction (subtract $y from $x)
1588 $x->bmul($y); # multiplication (multiply $x by $y)
1589 $x->bdiv($y); # divide, set $i to quotient
1590 # return (quo,rem) or quo if scalar
1592 $x->bmod($y); # modulus
1593 $x->bpow($y); # power of arguments (a**b)
1594 $x->blsft($y); # left shift
1595 $x->brsft($y); # right shift
1596 # return (quo,rem) or quo if scalar
1598 $x->blog($base); # logarithm of $x, base defaults to e
1599 # (other bases than e not supported yet)
1601 $x->band($y); # bit-wise and
1602 $x->bior($y); # bit-wise inclusive or
1603 $x->bxor($y); # bit-wise exclusive or
1604 $x->bnot(); # bit-wise not (two's complement)
1606 $x->bsqrt(); # calculate square-root
1607 $x->bfac(); # factorial of $x (1*2*3*4*..$x)
1609 $x->bround($N); # accuracy: preserver $N digits
1610 $x->bfround($N); # precision: round to the $Nth digit
1612 # The following do not modify their arguments:
1613 bgcd(@values); # greatest common divisor
1614 blcm(@values); # lowest common multiplicator
1616 $x->bstr(); # return string
1617 $x->bsstr(); # return string in scientific notation
1619 $x->bfloor(); # return integer less or equal than $x
1620 $x->bceil(); # return integer greater or equal than $x
1622 $x->exponent(); # return exponent as BigInt
1623 $x->mantissa(); # return mantissa as BigInt
1624 $x->parts(); # return (mantissa,exponent) as BigInt
1626 $x->length(); # number of digits (w/o sign and '.')
1627 ($l,$f) = $x->length(); # number of digits, and length of fraction
1631 All operators (inlcuding basic math operations) are overloaded if you
1632 declare your big floating point numbers as
1634 $i = new Math::BigFloat '12_3.456_789_123_456_789E-2';
1636 Operations with overloaded operators preserve the arguments, which is
1637 exactly what you expect.
1639 =head2 Canonical notation
1641 Input to these routines are either BigFloat objects, or strings of the
1642 following four forms:
1656 C</^[+-]\d+E[+-]?\d+$/>
1660 C</^[+-]\d*\.\d+E[+-]?\d+$/>
1664 all with optional leading and trailing zeros and/or spaces. Additonally,
1665 numbers are allowed to have an underscore between any two digits.
1667 Empty strings as well as other illegal numbers results in 'NaN'.
1669 bnorm() on a BigFloat object is now effectively a no-op, since the numbers
1670 are always stored in normalized form. On a string, it creates a BigFloat
1675 Output values are BigFloat objects (normalized), except for bstr() and bsstr().
1677 The string output will always have leading and trailing zeros stripped and drop
1678 a plus sign. C<bstr()> will give you always the form with a decimal point,
1679 while C<bsstr()> (for scientific) gives you the scientific notation.
1681 Input bstr() bsstr()
1683 ' -123 123 123' '-123123123' '-123123123E0'
1684 '00.0123' '0.0123' '123E-4'
1685 '123.45E-2' '1.2345' '12345E-4'
1686 '10E+3' '10000' '1E4'
1688 Some routines (C<is_odd()>, C<is_even()>, C<is_zero()>, C<is_one()>,
1689 C<is_nan()>) return true or false, while others (C<bcmp()>, C<bacmp()>)
1690 return either undef, <0, 0 or >0 and are suited for sort.
1692 Actual math is done by using BigInts to represent the mantissa and exponent.
1693 The sign C</^[+-]$/> is stored separately. The string 'NaN' is used to
1694 represent the result when input arguments are not numbers, as well as
1695 the result of dividing by zero.
1697 =head2 C<mantissa()>, C<exponent()> and C<parts()>
1699 C<mantissa()> and C<exponent()> return the said parts of the BigFloat
1700 as BigInts such that:
1702 $m = $x->mantissa();
1703 $e = $x->exponent();
1704 $y = $m * ( 10 ** $e );
1705 print "ok\n" if $x == $y;
1707 C<< ($m,$e) = $x->parts(); >> is just a shortcut giving you both of them.
1709 A zero is represented and returned as C<0E1>, B<not> C<0E0> (after Knuth).
1711 Currently the mantissa is reduced as much as possible, favouring higher
1712 exponents over lower ones (e.g. returning 1e7 instead of 10e6 or 10000000e0).
1713 This might change in the future, so do not depend on it.
1715 =head2 Accuracy vs. Precision
1717 See also: L<Rounding|Rounding>.
1719 Math::BigFloat supports both precision and accuracy. For a full documentation,
1720 examples and tips on these topics please see the large section in
1723 Since things like sqrt(2) or 1/3 must presented with a limited precision lest
1724 a operation consumes all resources, each operation produces no more than
1725 C<Math::BigFloat::precision()> digits.
1727 In case the result of one operation has more precision than specified,
1728 it is rounded. The rounding mode taken is either the default mode, or the one
1729 supplied to the operation after the I<scale>:
1731 $x = Math::BigFloat->new(2);
1732 Math::BigFloat::precision(5); # 5 digits max
1733 $y = $x->copy()->bdiv(3); # will give 0.66666
1734 $y = $x->copy()->bdiv(3,6); # will give 0.666666
1735 $y = $x->copy()->bdiv(3,6,'odd'); # will give 0.666667
1736 Math::BigFloat::round_mode('zero');
1737 $y = $x->copy()->bdiv(3,6); # will give 0.666666
1743 =item ffround ( +$scale )
1745 Rounds to the $scale'th place left from the '.', counting from the dot.
1746 The first digit is numbered 1.
1748 =item ffround ( -$scale )
1750 Rounds to the $scale'th place right from the '.', counting from the dot.
1754 Rounds to an integer.
1756 =item fround ( +$scale )
1758 Preserves accuracy to $scale digits from the left (aka significant digits)
1759 and pads the rest with zeros. If the number is between 1 and -1, the
1760 significant digits count from the first non-zero after the '.'
1762 =item fround ( -$scale ) and fround ( 0 )
1764 These are effetively no-ops.
1768 All rounding functions take as a second parameter a rounding mode from one of
1769 the following: 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'.
1771 The default rounding mode is 'even'. By using
1772 C<< Math::BigFloat::round_mode($round_mode); >> you can get and set the default
1773 mode for subsequent rounding. The usage of C<$Math::BigFloat::$round_mode> is
1774 no longer supported.
1775 The second parameter to the round functions then overrides the default
1778 The C<< as_number() >> function returns a BigInt from a Math::BigFloat. It uses
1779 'trunc' as rounding mode to make it equivalent to:
1784 You can override this by passing the desired rounding mode as parameter to
1787 $x = Math::BigFloat->new(2.5);
1788 $y = $x->as_number('odd'); # $y = 3
1794 =head1 Autocreating constants
1796 After C<use Math::BigFloat ':constant'> all the floating point constants
1797 in the given scope are converted to C<Math::BigFloat>. This conversion
1798 happens at compile time.
1802 perl -MMath::BigFloat=:constant -e 'print 2E-100,"\n"'
1804 prints the value of C<2E-100>. Note that without conversion of
1805 constants the expression 2E-100 will be calculated as normal floating point
1814 The following does not work yet:
1816 $m = $x->mantissa();
1817 $e = $x->exponent();
1818 $y = $m * ( 10 ** $e );
1819 print "ok\n" if $x == $y;
1823 There is no fmod() function yet.
1831 =item stringify, bstr()
1833 Both stringify and bstr() now drop the leading '+'. The old code would return
1834 '+1.23', the new returns '1.23'. See the documentation in L<Math::BigInt> for
1835 reasoning and details.
1839 The following will probably not do what you expect:
1841 print $c->bdiv(123.456),"\n";
1843 It prints both quotient and reminder since print works in list context. Also,
1844 bdiv() will modify $c, so be carefull. You probably want to use
1846 print $c / 123.456,"\n";
1847 print scalar $c->bdiv(123.456),"\n"; # or if you want to modify $c
1851 =item Modifying and =
1855 $x = Math::BigFloat->new(5);
1858 It will not do what you think, e.g. making a copy of $x. Instead it just makes
1859 a second reference to the B<same> object and stores it in $y. Thus anything
1860 that modifies $x will modify $y, and vice versa.
1863 print "$x, $y\n"; # prints '10, 10'
1865 If you want a true copy of $x, use:
1869 See also the documentation in L<overload> regarding C<=>.
1873 C<bpow()> now modifies the first argument, unlike the old code which left
1874 it alone and only returned the result. This is to be consistent with
1875 C<badd()> etc. The first will modify $x, the second one won't:
1877 print bpow($x,$i),"\n"; # modify $x
1878 print $x->bpow($i),"\n"; # ditto
1879 print $x ** $i,"\n"; # leave $x alone
1885 This program is free software; you may redistribute it and/or modify it under
1886 the same terms as Perl itself.
1890 Mark Biggar, overloaded interface by Ilya Zakharevich.
1891 Completely rewritten by Tels http://bloodgate.com in 2001.