1 package Math::BigFloat;
4 # Mike grinned. 'Two down, infinity to go' - Mike Nostrus in Before and After
7 # The following hash values are internally used:
8 # _e: exponent (BigInt)
9 # _m: mantissa (absolute BigInt)
10 # sign: +,-,"NaN" if not a number
13 # _f: flags, used to signal MBI not to touch our private parts
18 use Math::BigInt qw/objectify/;
19 @ISA = qw( Exporter Math::BigInt);
22 use vars qw/$AUTOLOAD $accuracy $precision $div_scale $round_mode $rnd_mode/;
23 use vars qw/$upgrade $downgrade/;
24 my $class = "Math::BigFloat";
27 '<=>' => sub { $_[2] ?
28 ref($_[0])->bcmp($_[1],$_[0]) :
29 ref($_[0])->bcmp($_[0],$_[1])},
30 'int' => sub { $_[0]->as_number() }, # 'trunc' to bigint
33 ##############################################################################
34 # global constants, flags and accessory
36 use constant MB_NEVER_ROUND => 0x0001;
40 # constant for easier life
43 # class constants, use Class->constant_name() to access
44 $round_mode = 'even'; # one of 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'
52 ##############################################################################
53 # the old code had $rnd_mode, so we need to support it, too
56 sub TIESCALAR { my ($class) = @_; bless \$round_mode, $class; }
57 sub FETCH { return $round_mode; }
58 sub STORE { $rnd_mode = $_[0]->round_mode($_[1]); }
60 BEGIN { tie $rnd_mode, 'Math::BigFloat'; }
62 ##############################################################################
64 # in case we call SUPER::->foo() and this wants to call modify()
65 # sub modify () { 0; }
68 # valid method aliases for AUTOLOAD
69 my %methods = map { $_ => 1 }
70 qw / fadd fsub fmul fdiv fround ffround fsqrt fmod fstr fsstr fpow fnorm
71 fint facmp fcmp fzero fnan finf finc fdec flog ffac
72 fceil ffloor frsft flsft fone flog
74 # valid method's that can be hand-ed up (for AUTOLOAD)
75 my %hand_ups = map { $_ => 1 }
76 qw / is_nan is_inf is_negative is_positive
77 accuracy precision div_scale round_mode fneg fabs babs fnot
78 objectify upgrade downgrade
82 sub method_alias { return exists $methods{$_[0]||''}; }
83 sub method_hand_up { return exists $hand_ups{$_[0]||''}; }
86 ##############################################################################
91 # create a new BigFloat object from a string or another bigfloat object.
94 # sign => sign (+/-), or "NaN"
96 my ($class,$wanted,@r) = @_;
98 # avoid numify-calls by not using || on $wanted!
99 return $class->bzero() if !defined $wanted; # default to 0
100 return $wanted->copy() if UNIVERSAL::isa($wanted,'Math::BigFloat');
102 my $self = {}; bless $self, $class;
103 # shortcut for bigints and its subclasses
104 if ((ref($wanted)) && (ref($wanted) ne $class))
106 $self->{_m} = $wanted->as_number(); # get us a bigint copy
107 $self->{_e} = Math::BigInt->bzero();
109 $self->{sign} = $wanted->sign();
110 return $self->bnorm();
113 # handle '+inf', '-inf' first
114 if ($wanted =~ /^[+-]?inf$/)
116 return $downgrade->new($wanted) if $downgrade;
118 $self->{_e} = Math::BigInt->bzero();
119 $self->{_m} = Math::BigInt->bzero();
120 $self->{sign} = $wanted;
121 $self->{sign} = '+inf' if $self->{sign} eq 'inf';
122 return $self->bnorm();
124 #print "new string '$wanted'\n";
125 my ($mis,$miv,$mfv,$es,$ev) = Math::BigInt::_split(\$wanted);
128 die "$wanted is not a number initialized to $class" if !$NaNOK;
130 return $downgrade->bnan() if $downgrade;
132 $self->{_e} = Math::BigInt->bzero();
133 $self->{_m} = Math::BigInt->bzero();
134 $self->{sign} = $nan;
138 # make integer from mantissa by adjusting exp, then convert to bigint
139 # undef,undef to signal MBI that we don't need no bloody rounding
140 $self->{_e} = Math::BigInt->new("$$es$$ev",undef,undef); # exponent
141 $self->{_m} = Math::BigInt->new("$$miv$$mfv",undef,undef); # create mant.
142 # 3.123E0 = 3123E-3, and 3.123E-2 => 3123E-5
143 $self->{_e} -= CORE::length($$mfv) if CORE::length($$mfv) != 0;
144 $self->{sign} = $$mis;
146 # if downgrade, inf, NaN or integers go down
148 if ($downgrade && $self->{_e}->{sign} eq '+')
150 # print "downgrading $$miv$$mfv"."E$$es$$ev";
151 if ($self->{_e}->is_zero())
153 $self->{_m}->{sign} = $$mis; # negative if wanted
154 return $downgrade->new($self->{_m});
156 return $downgrade->new("$$mis$$miv$$mfv"."E$$es$$ev");
159 # print "mbf new $self->{sign} $self->{_m} e $self->{_e}\n";
160 $self->bnorm()->round(@r); # first normalize, then round
165 # used by parent class bone() to initialize number to 1
167 $self->{_m} = Math::BigInt->bzero();
168 $self->{_e} = Math::BigInt->bzero();
173 # used by parent class bone() to initialize number to 1
175 $self->{_m} = Math::BigInt->bzero();
176 $self->{_e} = Math::BigInt->bzero();
181 # used by parent class bone() to initialize number to 1
183 $self->{_m} = Math::BigInt->bone();
184 $self->{_e} = Math::BigInt->bzero();
189 # used by parent class bone() to initialize number to 1
191 $self->{_m} = Math::BigInt->bzero();
192 $self->{_e} = Math::BigInt->bone();
195 ##############################################################################
196 # string conversation
200 # (ref to BFLOAT or num_str ) return num_str
201 # Convert number from internal format to (non-scientific) string format.
202 # internal format is always normalized (no leading zeros, "-0" => "+0")
203 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
204 #my $x = shift; my $class = ref($x) || $x;
205 #$x = $class->new(shift) unless ref($x);
207 #die "Oups! e was $nan" if $x->{_e}->{sign} eq $nan;
208 #die "Oups! m was $nan" if $x->{_m}->{sign} eq $nan;
209 if ($x->{sign} !~ /^[+-]$/)
211 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
215 my $es = '0'; my $len = 1; my $cad = 0; my $dot = '.';
217 my $not_zero = ! $x->is_zero();
220 $es = $x->{_m}->bstr();
221 $len = CORE::length($es);
222 if (!$x->{_e}->is_zero())
224 if ($x->{_e}->sign() eq '-')
227 if ($x->{_e} <= -$len)
229 # print "style: 0.xxxx\n";
230 my $r = $x->{_e}->copy(); $r->babs()->bsub( CORE::length($es) );
231 $es = '0.'. ('0' x $r) . $es; $cad = -($len+$r);
235 # print "insert '.' at $x->{_e} in '$es'\n";
236 substr($es,$x->{_e},0) = '.'; $cad = $x->{_e};
242 $es .= '0' x $x->{_e}; $len += $x->{_e}; $cad = 0;
246 $es = $x->{sign}.$es if $x->{sign} eq '-';
247 # if set accuracy or precision, pad with zeros
248 if ((defined $x->{_a}) && ($not_zero))
250 # 123400 => 6, 0.1234 => 4, 0.001234 => 4
251 my $zeros = $x->{_a} - $cad; # cad == 0 => 12340
252 $zeros = $x->{_a} - $len if $cad != $len;
253 $es .= $dot.'0' x $zeros if $zeros > 0;
255 elsif ($x->{_p} || 0 < 0)
257 # 123400 => 6, 0.1234 => 4, 0.001234 => 6
258 my $zeros = -$x->{_p} + $cad;
259 $es .= $dot.'0' x $zeros if $zeros > 0;
266 # (ref to BFLOAT or num_str ) return num_str
267 # Convert number from internal format to scientific string format.
268 # internal format is always normalized (no leading zeros, "-0E0" => "+0E0")
269 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
270 #my $x = shift; my $class = ref($x) || $x;
271 #$x = $class->new(shift) unless ref($x);
273 #die "Oups! e was $nan" if $x->{_e}->{sign} eq $nan;
274 #die "Oups! m was $nan" if $x->{_m}->{sign} eq $nan;
275 if ($x->{sign} !~ /^[+-]$/)
277 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
280 my $sign = $x->{_e}->{sign}; $sign = '' if $sign eq '-';
282 return $x->{_m}->bstr().$sep.$x->{_e}->bstr();
287 # Make a number from a BigFloat object
288 # simple return string and let Perl's atoi()/atof() handle the rest
289 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
293 ##############################################################################
294 # public stuff (usually prefixed with "b")
297 # todo: this must be overwritten and return NaN for non-integer values
298 # band(), bior(), bxor(), too
301 # $class->SUPER::bnot($class,@_);
306 # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
307 # (BFLOAT or num_str, BFLOAT or num_str) return cond_code
308 my ($self,$x,$y) = objectify(2,@_);
310 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
312 # handle +-inf and NaN
313 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
314 return 0 if ($x->{sign} eq $y->{sign}) && ($x->{sign} =~ /^[+-]inf$/);
315 return +1 if $x->{sign} eq '+inf';
316 return -1 if $x->{sign} eq '-inf';
317 return -1 if $y->{sign} eq '+inf';
321 # check sign for speed first
322 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
323 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
326 my $xz = $x->is_zero();
327 my $yz = $y->is_zero();
328 return 0 if $xz && $yz; # 0 <=> 0
329 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
330 return 1 if $yz && $x->{sign} eq '+'; # +x <=> 0
332 # adjust so that exponents are equal
333 my $lxm = $x->{_m}->length();
334 my $lym = $y->{_m}->length();
335 # the numify somewhat limits our length, but makes it much faster
336 my $lx = $lxm + $x->{_e}->numify();
337 my $ly = $lym + $y->{_e}->numify();
338 my $l = $lx - $ly; $l = -$l if $x->{sign} eq '-';
339 return $l <=> 0 if $l != 0;
341 # lengths (corrected by exponent) are equal
342 # so make mantissa equal length by padding with zero (shift left)
343 my $diff = $lxm - $lym;
344 my $xm = $x->{_m}; # not yet copy it
348 $ym = $y->{_m}->copy()->blsft($diff,10);
352 $xm = $x->{_m}->copy()->blsft(-$diff,10);
354 my $rc = $xm->bacmp($ym);
355 $rc = -$rc if $x->{sign} eq '-'; # -124 < -123
361 # Compares 2 values, ignoring their signs.
362 # Returns one of undef, <0, =0, >0. (suitable for sort)
363 # (BFLOAT or num_str, BFLOAT or num_str) return cond_code
364 my ($self,$x,$y) = objectify(2,@_);
366 # handle +-inf and NaN's
367 if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/)
369 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
370 return 0 if ($x->is_inf() && $y->is_inf());
371 return 1 if ($x->is_inf() && !$y->is_inf());
376 my $xz = $x->is_zero();
377 my $yz = $y->is_zero();
378 return 0 if $xz && $yz; # 0 <=> 0
379 return -1 if $xz && !$yz; # 0 <=> +y
380 return 1 if $yz && !$xz; # +x <=> 0
382 # adjust so that exponents are equal
383 my $lxm = $x->{_m}->length();
384 my $lym = $y->{_m}->length();
385 # the numify somewhat limits our length, but makes it much faster
386 my $lx = $lxm + $x->{_e}->numify();
387 my $ly = $lym + $y->{_e}->numify();
389 return $l <=> 0 if $l != 0;
391 # lengths (corrected by exponent) are equal
392 # so make mantissa equal-length by padding with zero (shift left)
393 my $diff = $lxm - $lym;
394 my $xm = $x->{_m}; # not yet copy it
398 $ym = $y->{_m}->copy()->blsft($diff,10);
402 $xm = $x->{_m}->copy()->blsft(-$diff,10);
404 $xm->bacmp($ym) <=> 0;
409 # add second arg (BFLOAT or string) to first (BFLOAT) (modifies first)
410 # return result as BFLOAT
411 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
413 #print "mbf badd $x $y\n";
414 # inf and NaN handling
415 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
418 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
420 if (($x->{sign} =~ /^[+-]inf$/) && ($y->{sign} =~ /^[+-]inf$/))
422 # +inf++inf or -inf+-inf => same, rest is NaN
423 return $x if $x->{sign} eq $y->{sign};
426 # +-inf + something => +inf
427 # something +-inf => +-inf
428 $x->{sign} = $y->{sign}, return $x if $y->{sign} =~ /^[+-]inf$/;
432 # speed: no add for 0+y or x+0
433 return $x->bround($a,$p,$r) if $y->is_zero(); # x+0
434 if ($x->is_zero()) # 0+y
436 # make copy, clobbering up x (modify in place!)
437 $x->{_e} = $y->{_e}->copy();
438 $x->{_m} = $y->{_m}->copy();
439 $x->{sign} = $y->{sign} || $nan;
440 return $x->round($a,$p,$r,$y);
443 # take lower of the two e's and adapt m1 to it to match m2
445 $e = Math::BigInt::bzero() if !defined $e; # if no BFLOAT ?
446 $e = $e->copy(); # make copy (didn't do it yet)
448 my $add = $y->{_m}->copy();
450 if ($e->{sign} eq '-') # < 0
452 my $e1 = $e->copy()->babs();
453 #$x->{_m} *= (10 ** $e1);
454 $x->{_m}->blsft($e1,10);
455 $x->{_e} += $e; # need the sign of e
458 elsif (!$e->is_zero()) # > 0
463 # else: both e are the same, so just leave them
464 $x->{_m}->{sign} = $x->{sign}; # fiddle with signs
465 $add->{sign} = $y->{sign};
466 $x->{_m} += $add; # finally do add/sub
467 $x->{sign} = $x->{_m}->{sign}; # re-adjust signs
468 $x->{_m}->{sign} = '+'; # mantissa always positiv
469 # delete trailing zeros, then round
470 return $x->bnorm()->round($a,$p,$r,$y);
475 # (BigFloat or num_str, BigFloat or num_str) return BigFloat
476 # subtract second arg from first, modify first
477 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
479 if ($y->is_zero()) # still round for not adding zero
481 return $x->round($a,$p,$r);
484 $y->{sign} =~ tr/+\-/-+/; # does nothing for NaN
485 $x->badd($y,$a,$p,$r); # badd does not leave internal zeros
486 $y->{sign} =~ tr/+\-/-+/; # refix $y (does nothing for NaN)
487 $x; # already rounded by badd()
492 # increment arg by one
493 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
495 if ($x->{_e}->sign() eq '-')
497 return $x->badd($self->bone(),$a,$p,$r); # digits after dot
500 if (!$x->{_e}->is_zero())
502 $x->{_m}->blsft($x->{_e},10); # 1e2 => 100
506 if ($x->{sign} eq '+')
509 return $x->bnorm()->bround($a,$p,$r);
511 elsif ($x->{sign} eq '-')
514 $x->{sign} = '+' if $x->{_m}->is_zero(); # -1 +1 => -0 => +0
515 return $x->bnorm()->bround($a,$p,$r);
517 # inf, nan handling etc
518 $x->badd($self->__one(),$a,$p,$r); # does round
523 # decrement arg by one
524 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
526 if ($x->{_e}->sign() eq '-')
528 return $x->badd($self->bone('-'),$a,$p,$r); # digits after dot
531 if (!$x->{_e}->is_zero())
533 $x->{_m}->blsft($x->{_e},10); # 1e2 => 100
537 my $zero = $x->is_zero();
539 if (($x->{sign} eq '-') || $zero)
542 $x->{sign} = '-' if $zero; # 0 => 1 => -1
543 $x->{sign} = '+' if $x->{_m}->is_zero(); # -1 +1 => -0 => +0
544 return $x->bnorm()->round($a,$p,$r);
547 elsif ($x->{sign} eq '+')
550 return $x->bnorm()->round($a,$p,$r);
552 # inf, nan handling etc
553 $x->badd($self->bone('-'),$a,$p,$r); # does round
558 my ($self,$x,$base,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(2,@_);
560 # http://www.efunda.com/math/taylor_series/logarithmic.cfm?search_string=log
564 # taylor: | u 1 u^3 1 u^5 |
565 # ln (x) = 2 | --- + - * --- + - * --- + ... | x > 0
566 # |_ v 3 v^3 5 v^5 _|
568 # we need to limit the accuracy to protect against overflow
571 my @params = $x->_find_round_parameters($a,$p,$r);
573 # no rounding at all, so must use fallback
574 if (scalar @params == 1)
576 # simulate old behaviour
577 $params[1] = $self->div_scale(); # and round to it as accuracy
578 $scale = $params[1]+4; # at least four more for proper round
579 $params[3] = $r; # round mode by caller or undef
580 $fallback = 1; # to clear a/p afterwards
584 # the 4 below is empirical, and there might be cases where it is not
586 $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined
589 return $x->bzero(@params) if $x->is_one();
590 return $x->bnan() if $x->{sign} ne '+' || $x->is_zero();
591 #return $x->bone('+',@params) if $x->bcmp($base) == 0;
593 # when user set globals, they would interfere with our calculation, so
594 # disable then and later re-enable them
596 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
597 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
598 # we also need to disable any set A or P on $x (_find_round_parameters took
599 # them already into account), since these would interfere, too
600 delete $x->{_a}; delete $x->{_p};
601 # need to disable $upgrade in BigInt, to aoid deep recursion
602 local $Math::BigInt::upgrade = undef;
604 my $v = $x->copy(); $v->binc(); # v = x+1
605 $x->bdec(); my $u = $x->copy(); # u = x-1; x = x-1
607 $x->bdiv($v,$scale); # first term: u/v
609 my $below = $v->copy();
610 my $over = $u->copy();
611 $u *= $u; $v *= $v; # u^2, v^2
612 $below->bmul($v); # u^3, v^3
614 my $factor = $self->new(3); my $two = $self->new(2);
616 my $diff = $self->bone();
617 my $limit = $self->new("1E-". ($scale-1)); my $last;
618 # print "diff $diff limit $limit\n";
619 while ($diff->bcmp($limit) > 0)
621 #print "$x $over $below $factor\n";
622 $diff = $x->copy()->bsub($last)->babs();
623 #print "diff $diff $limit\n";
625 $x += $over->copy()->bdiv($below->copy()->bmul($factor),$scale);
626 $over *= $u; $below *= $v; $factor->badd($two);
630 # shortcut to not run trough _find_round_parameters again
631 if (defined $params[1])
633 $x->bround($params[1],$params[3]); # then round accordingly
637 $x->bfround($params[2],$params[3]); # then round accordingly
641 # clear a/p after round, since user did not request it
642 $x->{_a} = undef; $x->{_p} = undef;
645 $$abr = $ab; $$pbr = $pb;
652 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
653 # does not modify arguments, but returns new object
654 # Lowest Common Multiplicator
656 my ($self,@arg) = objectify(0,@_);
657 my $x = $self->new(shift @arg);
658 while (@arg) { $x = _lcm($x,shift @arg); }
664 # (BFLOAT or num_str, BFLOAT or num_str) return BINT
665 # does not modify arguments, but returns new object
666 # GCD -- Euclids algorithm Knuth Vol 2 pg 296
668 my ($self,@arg) = objectify(0,@_);
669 my $x = $self->new(shift @arg);
670 while (@arg) { $x = _gcd($x,shift @arg); }
674 ###############################################################################
675 # is_foo methods (is_negative, is_positive are inherited from BigInt)
679 # return true if arg (BFLOAT or num_str) is an integer
680 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
682 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
683 $x->{_e}->{sign} eq '+'; # 1e-1 => no integer
689 # return true if arg (BFLOAT or num_str) is zero
690 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
692 return 1 if $x->{sign} eq '+' && $x->{_m}->is_zero();
698 # return true if arg (BFLOAT or num_str) is +1 or -1 if signis given
699 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
701 my $sign = shift || ''; $sign = '+' if $sign ne '-';
703 if ($x->{sign} eq $sign && $x->{_e}->is_zero() && $x->{_m}->is_one());
709 # return true if arg (BFLOAT or num_str) is odd or false if even
710 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
712 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
713 ($x->{_e}->is_zero() && $x->{_m}->is_odd());
719 # return true if arg (BINT or num_str) is even or false if odd
720 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
722 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
723 return 1 if ($x->{_e}->{sign} eq '+' # 123.45 is never
724 && $x->{_m}->is_even()); # but 1200 is
730 # multiply two numbers -- stolen from Knuth Vol 2 pg 233
731 # (BINT or num_str, BINT or num_str) return BINT
732 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
734 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
737 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
739 return $x->bnan() if $x->is_zero() || $y->is_zero();
740 # result will always be +-inf:
741 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
742 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
743 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
744 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
745 return $x->binf('-');
748 return $x->bzero() if $x->is_zero() || $y->is_zero();
750 # aEb * cEd = (a*c)E(b+d)
751 $x->{_m}->bmul($y->{_m});
752 $x->{_e}->badd($y->{_e});
754 $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
755 return $x->bnorm()->round($a,$p,$r,$y);
760 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return
761 # (BFLOAT,BFLOAT) (quo,rem) or BINT (only rem)
762 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
764 return $self->_div_inf($x,$y)
765 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
767 # x== 0 # also: or y == 1 or y == -1
768 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
771 return $upgrade->bdiv($x,$y,$a,$p,$r) if defined $upgrade;
773 # we need to limit the accuracy to protect against overflow
776 my @params = $x->_find_round_parameters($a,$p,$r,$y);
778 # no rounding at all, so must use fallback
779 if (scalar @params == 1)
781 # simulate old behaviour
782 $params[1] = $self->div_scale(); # and round to it as accuracy
783 $scale = $params[1]+4; # at least four more for proper round
784 $params[3] = $r; # round mode by caller or undef
785 $fallback = 1; # to clear a/p afterwards
789 # the 4 below is empirical, and there might be cases where it is not
791 $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined
793 my $lx = $x->{_m}->length(); my $ly = $y->{_m}->length();
794 $scale = $lx if $lx > $scale;
795 $scale = $ly if $ly > $scale;
796 my $diff = $ly - $lx;
797 $scale += $diff if $diff > 0; # if lx << ly, but not if ly << lx!
799 # make copy of $x in case of list context for later reminder calculation
801 if (wantarray && !$y->is_one())
806 $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
808 # check for / +-1 ( +/- 1E0)
811 # promote BigInts and it's subclasses (except when already a BigFloat)
812 $y = $self->new($y) unless $y->isa('Math::BigFloat');
814 # calculate the result to $scale digits and then round it
815 # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
816 $x->{_m}->blsft($scale,10);
817 $x->{_m}->bdiv( $y->{_m} ); # a/c
818 $x->{_e}->bsub( $y->{_e} ); # b-d
819 $x->{_e}->bsub($scale); # correct for 10**scale
820 $x->bnorm(); # remove trailing 0's
823 # shortcut to not run trough _find_round_parameters again
824 if (defined $params[1])
826 $x->bround($params[1],$params[3]); # then round accordingly
830 $x->bfround($params[2],$params[3]); # then round accordingly
834 # clear a/p after round, since user did not request it
835 $x->{_a} = undef; $x->{_p} = undef;
842 $rem->bmod($y,$params[1],$params[2],$params[3]); # copy already done
846 $rem = $self->bzero();
850 # clear a/p after round, since user did not request it
851 $rem->{_a} = undef; $rem->{_p} = undef;
860 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return reminder
861 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
863 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
865 my ($d,$re) = $self->SUPER::_div_inf($x,$y);
866 return $re->round($a,$p,$r,$y);
868 return $x->bnan() if $x->is_zero() && $y->is_zero();
869 return $x if $y->is_zero();
870 return $x->bnan() if $x->is_nan() || $y->is_nan();
871 return $x->bzero() if $y->is_one() || $x->is_zero();
873 # inf handling is missing here
875 my $cmp = $x->bacmp($y); # equal or $x < $y?
876 return $x->bzero($a,$p) if $cmp == 0; # $x == $y => result 0
878 # only $y of the operands negative?
879 my $neg = 0; $neg = 1 if $x->{sign} ne $y->{sign};
881 $x->{sign} = $y->{sign}; # calc sign first
882 return $x->round($a,$p,$r) if $cmp < 0 && $neg == 0; # $x < $y => result $x
884 my $ym = $y->{_m}->copy();
887 $ym->blsft($y->{_e},10) if $y->{_e}->{sign} eq '+' && !$y->{_e}->is_zero();
889 # if $y has digits after dot
890 my $shifty = 0; # correct _e of $x by this
891 if ($y->{_e}->{sign} eq '-') # has digits after dot
893 # 123 % 2.5 => 1230 % 25 => 5 => 0.5
894 $shifty = $y->{_e}->copy()->babs(); # no more digits after dot
895 $x->blsft($shifty,10); # 123 => 1230, $y->{_m} is already 25
897 # $ym is now mantissa of $y based on exponent 0
899 my $shiftx = 0; # correct _e of $x by this
900 if ($x->{_e}->{sign} eq '-') # has digits after dot
902 # 123.4 % 20 => 1234 % 200
903 $shiftx = $x->{_e}->copy()->babs(); # no more digits after dot
904 $ym->blsft($shiftx,10);
906 # 123e1 % 20 => 1230 % 20
907 if ($x->{_e}->{sign} eq '+' && !$x->{_e}->is_zero())
909 $x->{_m}->blsft($x->{_e},10);
911 $x->{_e} = Math::BigInt->bzero() unless $x->{_e}->is_zero();
913 $x->{_e}->bsub($shiftx) if $shiftx != 0;
914 $x->{_e}->bsub($shifty) if $shifty != 0;
916 # now mantissas are equalized, exponent of $x is adjusted, so calc result
917 # $ym->{sign} = '-' if $neg; # bmod() will make the correction for us
921 $x->{sign} = '+' if $x->{_m}->is_zero(); # fix sign for -0
924 if ($neg != 0) # one of them negative => correct in place
929 $x->{sign} = '+' if $x->{_m}->is_zero(); # fix sign for -0
933 $x->round($a,$p,$r,$y); # round and return
938 # calculate square root; this should probably
939 # use a different test to see whether the accuracy we want is...
940 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
942 return $x->bnan() if $x->{sign} eq 'NaN' || $x->{sign} =~ /^-/; # <0, NaN
943 return $x if $x->{sign} eq '+inf'; # +inf
944 return $x if $x->is_zero() || $x->is_one();
946 # we need to limit the accuracy to protect against overflow
949 my @params = $x->_find_round_parameters($a,$p,$r);
951 # no rounding at all, so must use fallback
952 if (scalar @params == 1)
954 # simulate old behaviour
955 $params[1] = $self->div_scale(); # and round to it as accuracy
956 $scale = $params[1]+4; # at least four more for proper round
957 $params[3] = $r; # round mode by caller or undef
958 $fallback = 1; # to clear a/p afterwards
962 # the 4 below is empirical, and there might be cases where it is not
964 $scale = abs($params[1] || $params[2]) + 4; # take whatever is defined
967 # when user set globals, they would interfere with our calculation, so
968 # disable then and later re-enable them
970 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
971 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
972 # we also need to disable any set A or P on $x (_find_round_parameters took
973 # them already into account), since these would interfere, too
974 delete $x->{_a}; delete $x->{_p};
975 # need to disable $upgrade in BigInt, to aoid deep recursion
976 local $Math::BigInt::upgrade = undef;
978 my $xas = $x->as_number();
979 my $gs = $xas->copy()->bsqrt(); # some guess
981 if (($x->{_e}->{sign} ne '-') # guess can't be accurate if there are
982 # digits after the dot
983 && ($xas->bacmp($gs * $gs) == 0)) # guess hit the nail on the head?
986 $x->{_m} = $gs; $x->{_e} = Math::BigInt->bzero(); $x->bnorm();
987 # shortcut to not run trough _find_round_parameters again
988 if (defined $params[1])
990 $x->bround($params[1],$params[3]); # then round accordingly
994 $x->bfround($params[2],$params[3]); # then round accordingly
998 # clear a/p after round, since user did not request it
999 $x->{_a} = undef; $x->{_p} = undef;
1001 ${"$self\::accuracy"} = $ab; ${"$self\::precision"} = $pb;
1004 $gs = $self->new( $gs ); # BigInt to BigFloat
1006 my $lx = $x->{_m}->length();
1007 $scale = $lx if $scale < $lx;
1008 my $e = $self->new("1E-$scale"); # make test variable
1009 # return $x->bnan() if $e->sign() eq 'NaN';
1012 my $two = $self->new(2);
1014 # promote BigInts and it's subclasses (except when already a BigFloat)
1015 $y = $self->new($y) unless $y->isa('Math::BigFloat');
1020 $rem = $y->copy()->bdiv($gs,$scale)->badd($gs)->bdiv($two,$scale);
1021 $diff = $rem->copy()->bsub($gs)->babs();
1024 # copy over to modify $x
1025 $x->{_m} = $rem->{_m}; $x->{_e} = $rem->{_e};
1027 # shortcut to not run trough _find_round_parameters again
1028 if (defined $params[1])
1030 $x->bround($params[1],$params[3]); # then round accordingly
1034 $x->bfround($params[2],$params[3]); # then round accordingly
1038 # clear a/p after round, since user did not request it
1039 $x->{_a} = undef; $x->{_p} = undef;
1042 $$abr = $ab; $$pbr = $pb;
1048 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
1049 # compute factorial numbers
1050 # modifies first argument
1051 my ($self,$x,@r) = objectify(1,@_);
1054 if (($x->{sign} ne '+') || # inf, NaN, <0 etc => NaN
1055 ($x->{_e}->{sign} ne '+')); # digits after dot?
1057 return $x->bone(@r) if $x->is_zero() || $x->is_one(); # 0 or 1 => 1
1059 # use BigInt's bfac() for faster calc
1060 $x->{_m}->blsft($x->{_e},10); # un-norm m
1061 $x->{_e}->bzero(); # norm $x again
1062 $x->{_m}->bfac(); # factorial
1063 $x->bnorm()->round(@r);
1068 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
1069 # compute power of two numbers, second arg is used as integer
1070 # modifies first argument
1072 my ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
1074 return $x if $x->{sign} =~ /^[+-]inf$/;
1075 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
1076 return $x->bone() if $y->is_zero();
1077 return $x if $x->is_one() || $y->is_one();
1078 my $y1 = $y->as_number(); # make bigint (trunc)
1080 if ($x->{sign} eq '-' && $x->{_m}->is_one() && $x->{_e}->is_zero())
1082 # if $x == -1 and odd/even y => +1/-1 because +-1 ^ (+-1) => +-1
1083 return $y1->is_odd() ? $x : $x->babs(1);
1087 return $x if $y->{sign} eq '+'; # 0**y => 0 (if not y <= 0)
1088 # 0 ** -y => 1 / (0 ** y) => / 0! (1 / 0 => +inf)
1092 # calculate $x->{_m} ** $y and $x->{_e} * $y separately (faster)
1094 $x->{_m}->bpow($y1);
1095 $x->{_e}->bmul($y1);
1096 $x->{sign} = $nan if $x->{_m}->{sign} eq $nan || $x->{_e}->{sign} eq $nan;
1098 if ($y->{sign} eq '-')
1100 # modify $x in place!
1101 my $z = $x->copy(); $x->bzero()->binc();
1102 return $x->bdiv($z,$a,$p,$r); # round in one go (might ignore y's A!)
1104 $x->round($a,$p,$r,$y);
1107 ###############################################################################
1108 # rounding functions
1112 # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
1113 # $n == 0 means round to integer
1114 # expects and returns normalized numbers!
1115 my $x = shift; my $self = ref($x) || $x; $x = $self->new(shift) if !ref($x);
1117 return $x if $x->modify('bfround');
1119 my ($scale,$mode) = $x->_scale_p($self->precision(),$self->round_mode(),@_);
1120 return $x if !defined $scale; # no-op
1122 # never round a 0, +-inf, NaN
1125 $x->{_p} = $scale if !defined $x->{_p} || $x->{_p} < $scale; # -3 < -2
1128 return $x if $x->{sign} !~ /^[+-]$/;
1129 # print "MBF bfround $x to scale $scale mode $mode\n";
1131 # don't round if x already has lower precision
1132 return $x if (defined $x->{_p} && $x->{_p} < 0 && $scale < $x->{_p});
1134 $x->{_p} = $scale; # remember round in any case
1135 $x->{_a} = undef; # and clear A
1138 # print "bfround scale $scale e $x->{_e}\n";
1139 # round right from the '.'
1140 return $x if $x->{_e} >= 0; # nothing to round
1141 $scale = -$scale; # positive for simplicity
1142 my $len = $x->{_m}->length(); # length of mantissa
1143 my $dad = -$x->{_e}; # digits after dot
1144 my $zad = 0; # zeros after dot
1145 $zad = -$len-$x->{_e} if ($x->{_e} < -$len);# for 0.00..00xxx style
1146 #print "scale $scale dad $dad zad $zad len $len\n";
1148 # number bsstr len zad dad
1149 # 0.123 123e-3 3 0 3
1150 # 0.0123 123e-4 3 1 4
1153 # 1.2345 12345e-4 5 0 4
1155 # do not round after/right of the $dad
1156 return $x if $scale > $dad; # 0.123, scale >= 3 => exit
1158 # round to zero if rounding inside the $zad, but not for last zero like:
1159 # 0.0065, scale -2, round last '0' with following '65' (scale == zad case)
1160 return $x->bzero() if $scale < $zad;
1161 if ($scale == $zad) # for 0.006, scale -3 and trunc
1167 # adjust round-point to be inside mantissa
1170 $scale = $scale-$zad;
1174 my $dbd = $len - $dad; $dbd = 0 if $dbd < 0; # digits before dot
1175 $scale = $dbd+$scale;
1178 # print "round to $x->{_m} to $scale\n";
1182 # 123 => 100 means length(123) = 3 - $scale (2) => 1
1184 my $dbt = $x->{_m}->length();
1186 my $dbd = $dbt + $x->{_e};
1187 # should be the same, so treat it as this
1188 $scale = 1 if $scale == 0;
1189 # shortcut if already integer
1190 return $x if $scale == 1 && $dbt <= $dbd;
1191 # maximum digits before dot
1196 # not enough digits before dot, so round to zero
1199 elsif ( $scale == $dbd )
1206 $scale = $dbd - $scale;
1210 # print "using $scale for $x->{_m} with '$mode'\n";
1211 # pass sign to bround for rounding modes '+inf' and '-inf'
1212 $x->{_m}->{sign} = $x->{sign};
1213 $x->{_m}->bround($scale,$mode);
1214 $x->{_m}->{sign} = '+'; # fix sign back
1220 # accuracy: preserve $N digits, and overwrite the rest with 0's
1221 my $x = shift; my $self = ref($x) || $x; $x = $self->new(shift) if !ref($x);
1223 die ('bround() needs positive accuracy') if ($_[0] || 0) < 0;
1225 my ($scale,$mode) = $x->_scale_a($self->accuracy(),$self->round_mode(),@_);
1226 return $x if !defined $scale; # no-op
1228 return $x if $x->modify('bround');
1230 # scale is now either $x->{_a}, $accuracy, or the user parameter
1231 # test whether $x already has lower accuracy, do nothing in this case
1232 # but do round if the accuracy is the same, since a math operation might
1233 # want to round a number with A=5 to 5 digits afterwards again
1234 return $x if defined $_[0] && defined $x->{_a} && $x->{_a} < $_[0];
1236 # scale < 0 makes no sense
1237 # never round a +-inf, NaN
1238 return $x if ($scale < 0) || $x->{sign} !~ /^[+-]$/;
1240 # 1: $scale == 0 => keep all digits
1241 # 2: never round a 0
1242 # 3: if we should keep more digits than the mantissa has, do nothing
1243 if ($scale == 0 || $x->is_zero() || $x->{_m}->length() <= $scale)
1245 $x->{_a} = $scale if !defined $x->{_a} || $x->{_a} > $scale;
1249 # pass sign to bround for '+inf' and '-inf' rounding modes
1250 $x->{_m}->{sign} = $x->{sign};
1251 $x->{_m}->bround($scale,$mode); # round mantissa
1252 $x->{_m}->{sign} = '+'; # fix sign back
1253 # $x->{_m}->{_a} = undef; $x->{_m}->{_p} = undef;
1254 $x->{_a} = $scale; # remember rounding
1255 $x->{_p} = undef; # and clear P
1256 $x->bnorm(); # del trailing zeros gen. by bround()
1261 # return integer less or equal then $x
1262 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1264 return $x if $x->modify('bfloor');
1266 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1268 # if $x has digits after dot
1269 if ($x->{_e}->{sign} eq '-')
1271 #$x->{_m}->brsft(-$x->{_e},10);
1273 #$x-- if $x->{sign} eq '-';
1275 $x->{_e}->{sign} = '+'; # negate e
1276 $x->{_m}->brsft($x->{_e},10); # cut off digits after dot
1277 $x->{_e}->bzero(); # trunc/norm
1278 $x->{_m}->binc() if $x->{sign} eq '-'; # decrement if negative
1280 $x->round($a,$p,$r);
1285 # return integer greater or equal then $x
1286 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1288 return $x if $x->modify('bceil');
1289 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1291 # if $x has digits after dot
1292 if ($x->{_e}->{sign} eq '-')
1294 #$x->{_m}->brsft(-$x->{_e},10);
1296 #$x++ if $x->{sign} eq '+';
1298 $x->{_e}->{sign} = '+'; # negate e
1299 $x->{_m}->brsft($x->{_e},10); # cut off digits after dot
1300 $x->{_e}->bzero(); # trunc/norm
1301 $x->{_m}->binc() if $x->{sign} eq '+'; # decrement if negative
1303 $x->round($a,$p,$r);
1308 # shift right by $y (divide by power of 2)
1309 my ($self,$x,$y,$n,$a,$p,$r) = objectify(2,@_);
1311 return $x if $x->modify('brsft');
1312 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1314 $n = 2 if !defined $n; $n = Math::BigFloat->new($n);
1315 $x->bdiv($n ** $y,$a,$p,$r,$y);
1320 # shift right by $y (divide by power of 2)
1321 my ($self,$x,$y,$n,$a,$p,$r) = objectify(2,@_);
1323 return $x if $x->modify('brsft');
1324 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
1326 $n = 2 if !defined $n; $n = Math::BigFloat->new($n);
1327 $x->bmul($n ** $y,$a,$p,$r,$y);
1330 ###############################################################################
1334 # going through AUTOLOAD for every DESTROY is costly, so avoid it by empty sub
1339 # make fxxx and bxxx both work by selectively mapping fxxx() to MBF::bxxx()
1340 # or falling back to MBI::bxxx()
1341 my $name = $AUTOLOAD;
1343 $name =~ s/.*:://; # split package
1345 if (!method_alias($name))
1349 # delayed load of Carp and avoid recursion
1351 Carp::croak ("Can't call a method without name");
1353 if (!method_hand_up($name))
1355 # delayed load of Carp and avoid recursion
1357 Carp::croak ("Can't call $class\-\>$name, not a valid method");
1359 # try one level up, but subst. bxxx() for fxxx() since MBI only got bxxx()
1361 return &{'Math::BigInt'."::$name"}(@_);
1363 my $bname = $name; $bname =~ s/^f/b/;
1364 *{$class."::$name"} = \&$bname;
1370 # return a copy of the exponent
1371 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1373 if ($x->{sign} !~ /^[+-]$/)
1375 my $s = $x->{sign}; $s =~ s/^[+-]//;
1376 return $self->new($s); # -inf, +inf => +inf
1378 return $x->{_e}->copy();
1383 # return a copy of the mantissa
1384 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1386 if ($x->{sign} !~ /^[+-]$/)
1388 my $s = $x->{sign}; $s =~ s/^[+]//;
1389 return $self->new($s); # -inf, +inf => +inf
1391 my $m = $x->{_m}->copy(); # faster than going via bstr()
1392 $m->bneg() if $x->{sign} eq '-';
1399 # return a copy of both the exponent and the mantissa
1400 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1402 if ($x->{sign} !~ /^[+-]$/)
1404 my $s = $x->{sign}; $s =~ s/^[+]//; my $se = $s; $se =~ s/^[-]//;
1405 return ($self->new($s),$self->new($se)); # +inf => inf and -inf,+inf => inf
1407 my $m = $x->{_m}->copy(); # faster than going via bstr()
1408 $m->bneg() if $x->{sign} eq '-';
1409 return ($m,$x->{_e}->copy());
1412 ##############################################################################
1413 # private stuff (internal use only)
1418 my $l = scalar @_; my $j = 0; my @a = @_;
1419 for ( my $i = 0; $i < $l ; $i++, $j++)
1421 if ( $_[$i] eq ':constant' )
1423 # this rest causes overlord er load to step in
1424 # print "overload @_\n";
1425 overload::constant float => sub { $self->new(shift); };
1426 splice @a, $j, 1; $j--;
1428 elsif ($_[$i] eq 'upgrade')
1430 # this causes upgrading
1431 $upgrade = $_[$i+1]; # or undef to disable
1432 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
1433 splice @a, $j, $s; $j -= $s;
1435 elsif ($_[$i] eq 'downgrade')
1437 # this causes downgrading
1438 $downgrade = $_[$i+1]; # or undef to disable
1439 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
1440 splice @a, $j, $s; $j -= $s;
1443 # any non :constant stuff is handled by our parent, Exporter
1444 # even if @_ is empty, to give it a chance
1445 $self->SUPER::import(@a); # for subclasses
1446 $self->export_to_level(1,$self,@a); # need this, too
1451 # adjust m and e so that m is smallest possible
1452 # round number according to accuracy and precision settings
1453 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1455 return $x if $x->{sign} !~ /^[+-]$/; # inf, nan etc
1457 # if (!$x->{_m}->is_odd())
1459 my $zeros = $x->{_m}->_trailing_zeros(); # correct for trailing zeros
1462 $x->{_m}->brsft($zeros,10); $x->{_e}->badd($zeros);
1464 # for something like 0Ey, set y to 1, and -0 => +0
1465 $x->{sign} = '+', $x->{_e}->bone() if $x->{_m}->is_zero();
1467 # this is to prevent automatically rounding when MBI's globals are set
1468 $x->{_m}->{_f} = MB_NEVER_ROUND;
1469 $x->{_e}->{_f} = MB_NEVER_ROUND;
1470 # 'forget' that mantissa was rounded via MBI::bround() in MBF's bfround()
1471 $x->{_m}->{_a} = undef; $x->{_e}->{_a} = undef;
1472 $x->{_m}->{_p} = undef; $x->{_e}->{_p} = undef;
1473 $x; # MBI bnorm is no-op, so dont call it
1476 ##############################################################################
1477 # internal calculation routines
1481 # return copy as a bigint representation of this BigFloat number
1482 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
1484 my $z = $x->{_m}->copy();
1485 if ($x->{_e}->{sign} eq '-') # < 0
1487 $x->{_e}->{sign} = '+'; # flip
1488 $z->brsft($x->{_e},10);
1489 $x->{_e}->{sign} = '-'; # flip back
1491 elsif (!$x->{_e}->is_zero()) # > 0
1493 $z->blsft($x->{_e},10);
1495 $z->{sign} = $x->{sign};
1502 my $class = ref($x) || $x;
1503 $x = $class->new(shift) unless ref($x);
1505 return 1 if $x->{_m}->is_zero();
1506 my $len = $x->{_m}->length();
1507 $len += $x->{_e} if $x->{_e}->sign() eq '+';
1510 my $t = Math::BigInt::bzero();
1511 $t = $x->{_e}->copy()->babs() if $x->{_e}->sign() eq '-';
1522 Math::BigFloat - Arbitrary size floating point math package
1529 $x = Math::BigFloat->new($str); # defaults to 0
1530 $nan = Math::BigFloat->bnan(); # create a NotANumber
1531 $zero = Math::BigFloat->bzero(); # create a +0
1532 $inf = Math::BigFloat->binf(); # create a +inf
1533 $inf = Math::BigFloat->binf('-'); # create a -inf
1534 $one = Math::BigFloat->bone(); # create a +1
1535 $one = Math::BigFloat->bone('-'); # create a -1
1538 $x->is_zero(); # true if arg is +0
1539 $x->is_nan(); # true if arg is NaN
1540 $x->is_one(); # true if arg is +1
1541 $x->is_one('-'); # true if arg is -1
1542 $x->is_odd(); # true if odd, false for even
1543 $x->is_even(); # true if even, false for odd
1544 $x->is_positive(); # true if >= 0
1545 $x->is_negative(); # true if < 0
1546 $x->is_inf(sign); # true if +inf, or -inf (default is '+')
1548 $x->bcmp($y); # compare numbers (undef,<0,=0,>0)
1549 $x->bacmp($y); # compare absolutely (undef,<0,=0,>0)
1550 $x->sign(); # return the sign, either +,- or NaN
1551 $x->digit($n); # return the nth digit, counting from right
1552 $x->digit(-$n); # return the nth digit, counting from left
1554 # The following all modify their first argument:
1557 $x->bzero(); # set $i to 0
1558 $x->bnan(); # set $i to NaN
1559 $x->bone(); # set $x to +1
1560 $x->bone('-'); # set $x to -1
1561 $x->binf(); # set $x to inf
1562 $x->binf('-'); # set $x to -inf
1564 $x->bneg(); # negation
1565 $x->babs(); # absolute value
1566 $x->bnorm(); # normalize (no-op)
1567 $x->bnot(); # two's complement (bit wise not)
1568 $x->binc(); # increment x by 1
1569 $x->bdec(); # decrement x by 1
1571 $x->badd($y); # addition (add $y to $x)
1572 $x->bsub($y); # subtraction (subtract $y from $x)
1573 $x->bmul($y); # multiplication (multiply $x by $y)
1574 $x->bdiv($y); # divide, set $i to quotient
1575 # return (quo,rem) or quo if scalar
1577 $x->bmod($y); # modulus
1578 $x->bpow($y); # power of arguments (a**b)
1579 $x->blsft($y); # left shift
1580 $x->brsft($y); # right shift
1581 # return (quo,rem) or quo if scalar
1583 $x->blog($base); # logarithm of $x, base defaults to e
1584 # (other bases than e not supported yet)
1586 $x->band($y); # bit-wise and
1587 $x->bior($y); # bit-wise inclusive or
1588 $x->bxor($y); # bit-wise exclusive or
1589 $x->bnot(); # bit-wise not (two's complement)
1591 $x->bsqrt(); # calculate square-root
1592 $x->bfac(); # factorial of $x (1*2*3*4*..$x)
1594 $x->bround($N); # accuracy: preserver $N digits
1595 $x->bfround($N); # precision: round to the $Nth digit
1597 # The following do not modify their arguments:
1598 bgcd(@values); # greatest common divisor
1599 blcm(@values); # lowest common multiplicator
1601 $x->bstr(); # return string
1602 $x->bsstr(); # return string in scientific notation
1604 $x->bfloor(); # return integer less or equal than $x
1605 $x->bceil(); # return integer greater or equal than $x
1607 $x->exponent(); # return exponent as BigInt
1608 $x->mantissa(); # return mantissa as BigInt
1609 $x->parts(); # return (mantissa,exponent) as BigInt
1611 $x->length(); # number of digits (w/o sign and '.')
1612 ($l,$f) = $x->length(); # number of digits, and length of fraction
1616 All operators (inlcuding basic math operations) are overloaded if you
1617 declare your big floating point numbers as
1619 $i = new Math::BigFloat '12_3.456_789_123_456_789E-2';
1621 Operations with overloaded operators preserve the arguments, which is
1622 exactly what you expect.
1624 =head2 Canonical notation
1626 Input to these routines are either BigFloat objects, or strings of the
1627 following four forms:
1641 C</^[+-]\d+E[+-]?\d+$/>
1645 C</^[+-]\d*\.\d+E[+-]?\d+$/>
1649 all with optional leading and trailing zeros and/or spaces. Additonally,
1650 numbers are allowed to have an underscore between any two digits.
1652 Empty strings as well as other illegal numbers results in 'NaN'.
1654 bnorm() on a BigFloat object is now effectively a no-op, since the numbers
1655 are always stored in normalized form. On a string, it creates a BigFloat
1660 Output values are BigFloat objects (normalized), except for bstr() and bsstr().
1662 The string output will always have leading and trailing zeros stripped and drop
1663 a plus sign. C<bstr()> will give you always the form with a decimal point,
1664 while C<bsstr()> (for scientific) gives you the scientific notation.
1666 Input bstr() bsstr()
1668 ' -123 123 123' '-123123123' '-123123123E0'
1669 '00.0123' '0.0123' '123E-4'
1670 '123.45E-2' '1.2345' '12345E-4'
1671 '10E+3' '10000' '1E4'
1673 Some routines (C<is_odd()>, C<is_even()>, C<is_zero()>, C<is_one()>,
1674 C<is_nan()>) return true or false, while others (C<bcmp()>, C<bacmp()>)
1675 return either undef, <0, 0 or >0 and are suited for sort.
1677 Actual math is done by using BigInts to represent the mantissa and exponent.
1678 The sign C</^[+-]$/> is stored separately. The string 'NaN' is used to
1679 represent the result when input arguments are not numbers, as well as
1680 the result of dividing by zero.
1682 =head2 C<mantissa()>, C<exponent()> and C<parts()>
1684 C<mantissa()> and C<exponent()> return the said parts of the BigFloat
1685 as BigInts such that:
1687 $m = $x->mantissa();
1688 $e = $x->exponent();
1689 $y = $m * ( 10 ** $e );
1690 print "ok\n" if $x == $y;
1692 C<< ($m,$e) = $x->parts(); >> is just a shortcut giving you both of them.
1694 A zero is represented and returned as C<0E1>, B<not> C<0E0> (after Knuth).
1696 Currently the mantissa is reduced as much as possible, favouring higher
1697 exponents over lower ones (e.g. returning 1e7 instead of 10e6 or 10000000e0).
1698 This might change in the future, so do not depend on it.
1700 =head2 Accuracy vs. Precision
1702 See also: L<Rounding|Rounding>.
1704 Math::BigFloat supports both precision and accuracy. For a full documentation,
1705 examples and tips on these topics please see the large section in
1708 Since things like sqrt(2) or 1/3 must presented with a limited precision lest
1709 a operation consumes all resources, each operation produces no more than
1710 C<Math::BigFloat::precision()> digits.
1712 In case the result of one operation has more precision than specified,
1713 it is rounded. The rounding mode taken is either the default mode, or the one
1714 supplied to the operation after the I<scale>:
1716 $x = Math::BigFloat->new(2);
1717 Math::BigFloat::precision(5); # 5 digits max
1718 $y = $x->copy()->bdiv(3); # will give 0.66666
1719 $y = $x->copy()->bdiv(3,6); # will give 0.666666
1720 $y = $x->copy()->bdiv(3,6,'odd'); # will give 0.666667
1721 Math::BigFloat::round_mode('zero');
1722 $y = $x->copy()->bdiv(3,6); # will give 0.666666
1728 =item ffround ( +$scale )
1730 Rounds to the $scale'th place left from the '.', counting from the dot.
1731 The first digit is numbered 1.
1733 =item ffround ( -$scale )
1735 Rounds to the $scale'th place right from the '.', counting from the dot.
1739 Rounds to an integer.
1741 =item fround ( +$scale )
1743 Preserves accuracy to $scale digits from the left (aka significant digits)
1744 and pads the rest with zeros. If the number is between 1 and -1, the
1745 significant digits count from the first non-zero after the '.'
1747 =item fround ( -$scale ) and fround ( 0 )
1749 These are effetively no-ops.
1753 All rounding functions take as a second parameter a rounding mode from one of
1754 the following: 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'.
1756 The default rounding mode is 'even'. By using
1757 C<< Math::BigFloat::round_mode($round_mode); >> you can get and set the default
1758 mode for subsequent rounding. The usage of C<$Math::BigFloat::$round_mode> is
1759 no longer supported.
1760 The second parameter to the round functions then overrides the default
1763 The C<< as_number() >> function returns a BigInt from a Math::BigFloat. It uses
1764 'trunc' as rounding mode to make it equivalent to:
1769 You can override this by passing the desired rounding mode as parameter to
1772 $x = Math::BigFloat->new(2.5);
1773 $y = $x->as_number('odd'); # $y = 3
1779 =head1 Autocreating constants
1781 After C<use Math::BigFloat ':constant'> all the floating point constants
1782 in the given scope are converted to C<Math::BigFloat>. This conversion
1783 happens at compile time.
1787 perl -MMath::BigFloat=:constant -e 'print 2E-100,"\n"'
1789 prints the value of C<2E-100>. Note that without conversion of
1790 constants the expression 2E-100 will be calculated as normal floating point
1799 The following does not work yet:
1801 $m = $x->mantissa();
1802 $e = $x->exponent();
1803 $y = $m * ( 10 ** $e );
1804 print "ok\n" if $x == $y;
1808 There is no fmod() function yet.
1816 =item stringify, bstr()
1818 Both stringify and bstr() now drop the leading '+'. The old code would return
1819 '+1.23', the new returns '1.23'. See the documentation in L<Math::BigInt> for
1820 reasoning and details.
1824 The following will probably not do what you expect:
1826 print $c->bdiv(123.456),"\n";
1828 It prints both quotient and reminder since print works in list context. Also,
1829 bdiv() will modify $c, so be carefull. You probably want to use
1831 print $c / 123.456,"\n";
1832 print scalar $c->bdiv(123.456),"\n"; # or if you want to modify $c
1836 =item Modifying and =
1840 $x = Math::BigFloat->new(5);
1843 It will not do what you think, e.g. making a copy of $x. Instead it just makes
1844 a second reference to the B<same> object and stores it in $y. Thus anything
1845 that modifies $x will modify $y, and vice versa.
1848 print "$x, $y\n"; # prints '10, 10'
1850 If you want a true copy of $x, use:
1854 See also the documentation in L<overload> regarding C<=>.
1858 C<bpow()> now modifies the first argument, unlike the old code which left
1859 it alone and only returned the result. This is to be consistent with
1860 C<badd()> etc. The first will modify $x, the second one won't:
1862 print bpow($x,$i),"\n"; # modify $x
1863 print $x->bpow($i),"\n"; # ditto
1864 print $x ** $i,"\n"; # leave $x alone
1870 This program is free software; you may redistribute it and/or modify it under
1871 the same terms as Perl itself.
1875 Mark Biggar, overloaded interface by Ilya Zakharevich.
1876 Completely rewritten by Tels http://bloodgate.com in 2001.