This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Clean up POD for Math::BigInt and Math::BigFloat
[perl5.git] / dist / Math-BigInt / lib / Math / BigFloat.pm
... / ...
CommitLineData
1package Math::BigFloat;
2
3#
4# Mike grinned. 'Two down, infinity to go' - Mike Nostrus in 'Before and After'
5#
6
7# The following hash values are internally used:
8# _e : exponent (ref to $CALC object)
9# _m : mantissa (ref to $CALC object)
10# _es : sign of _e
11# sign : +,-,+inf,-inf, or "NaN" if not a number
12# _a : accuracy
13# _p : precision
14
15$VERSION = '1.999';
16require 5.006002;
17
18require Exporter;
19@ISA = qw/Math::BigInt/;
20@EXPORT_OK = qw/bpi/;
21
22use strict;
23# $_trap_inf/$_trap_nan are internal and should never be accessed from outside
24use vars qw/$AUTOLOAD $accuracy $precision $div_scale $round_mode $rnd_mode
25 $upgrade $downgrade $_trap_nan $_trap_inf/;
26my $class = "Math::BigFloat";
27
28use overload
29'<=>' => sub { my $rc = $_[2] ?
30 ref($_[0])->bcmp($_[1],$_[0]) :
31 ref($_[0])->bcmp($_[0],$_[1]);
32 $rc = 1 unless defined $rc;
33 $rc <=> 0;
34 },
35# we need '>=' to get things like "1 >= NaN" right:
36'>=' => sub { my $rc = $_[2] ?
37 ref($_[0])->bcmp($_[1],$_[0]) :
38 ref($_[0])->bcmp($_[0],$_[1]);
39 # if there was a NaN involved, return false
40 return '' unless defined $rc;
41 $rc >= 0;
42 },
43'int' => sub { $_[0]->as_number() }, # 'trunc' to bigint
44;
45
46##############################################################################
47# global constants, flags and assorted stuff
48
49# the following are public, but their usage is not recommended. Use the
50# accessor methods instead.
51
52# class constants, use Class->constant_name() to access
53# one of 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'
54$round_mode = 'even';
55$accuracy = undef;
56$precision = undef;
57$div_scale = 40;
58
59$upgrade = undef;
60$downgrade = undef;
61# the package we are using for our private parts, defaults to:
62# Math::BigInt->config()->{lib}
63my $MBI = 'Math::BigInt::Calc';
64
65# are NaNs ok? (otherwise it dies when encountering an NaN) set w/ config()
66$_trap_nan = 0;
67# the same for infinity
68$_trap_inf = 0;
69
70# constant for easier life
71my $nan = 'NaN';
72
73my $IMPORT = 0; # was import() called yet? used to make require work
74
75# some digits of accuracy for blog(undef,10); which we use in blog() for speed
76my $LOG_10 =
77 '2.3025850929940456840179914546843642076011014886287729760333279009675726097';
78my $LOG_10_A = length($LOG_10)-1;
79# ditto for log(2)
80my $LOG_2 =
81 '0.6931471805599453094172321214581765680755001343602552541206800094933936220';
82my $LOG_2_A = length($LOG_2)-1;
83my $HALF = '0.5'; # made into an object if nec.
84
85##############################################################################
86# the old code had $rnd_mode, so we need to support it, too
87
88sub TIESCALAR { my ($class) = @_; bless \$round_mode, $class; }
89sub FETCH { return $round_mode; }
90sub STORE { $rnd_mode = $_[0]->round_mode($_[1]); }
91
92BEGIN
93 {
94 # when someone sets $rnd_mode, we catch this and check the value to see
95 # whether it is valid or not.
96 $rnd_mode = 'even'; tie $rnd_mode, 'Math::BigFloat';
97
98 # we need both of them in this package:
99 *as_int = \&as_number;
100 }
101
102##############################################################################
103
104{
105 # valid method aliases for AUTOLOAD
106 my %methods = map { $_ => 1 }
107 qw / fadd fsub fmul fdiv fround ffround fsqrt fmod fstr fsstr fpow fnorm
108 fint facmp fcmp fzero fnan finf finc fdec ffac fneg
109 fceil ffloor frsft flsft fone flog froot fexp
110 /;
111 # valid methods that can be handed up (for AUTOLOAD)
112 my %hand_ups = map { $_ => 1 }
113 qw / is_nan is_inf is_negative is_positive is_pos is_neg
114 accuracy precision div_scale round_mode fabs fnot
115 objectify upgrade downgrade
116 bone binf bnan bzero
117 bsub
118 /;
119
120 sub _method_alias { exists $methods{$_[0]||''}; }
121 sub _method_hand_up { exists $hand_ups{$_[0]||''}; }
122}
123
124##############################################################################
125# constructors
126
127sub new
128 {
129 # create a new BigFloat object from a string or another bigfloat object.
130 # _e: exponent
131 # _m: mantissa
132 # sign => sign (+/-), or "NaN"
133
134 my ($class,$wanted,@r) = @_;
135
136 # avoid numify-calls by not using || on $wanted!
137 return $class->bzero() if !defined $wanted; # default to 0
138 return $wanted->copy() if UNIVERSAL::isa($wanted,'Math::BigFloat');
139
140 $class->import() if $IMPORT == 0; # make require work
141
142 my $self = {}; bless $self, $class;
143 # shortcut for bigints and its subclasses
144 if ((ref($wanted)) && UNIVERSAL::can( $wanted, "as_number"))
145 {
146 $self->{_m} = $wanted->as_number()->{value}; # get us a bigint copy
147 $self->{_e} = $MBI->_zero();
148 $self->{_es} = '+';
149 $self->{sign} = $wanted->sign();
150 return $self->bnorm();
151 }
152 # else: got a string or something masquerading as number (with overload)
153
154 # handle '+inf', '-inf' first
155 if ($wanted =~ /^[+-]?inf\z/)
156 {
157 return $downgrade->new($wanted) if $downgrade;
158
159 $self->{sign} = $wanted; # set a default sign for bstr()
160 return $self->binf($wanted);
161 }
162
163 # shortcut for simple forms like '12' that neither have trailing nor leading
164 # zeros
165 if ($wanted =~ /^([+-]?)([1-9][0-9]*[1-9])$/)
166 {
167 $self->{_e} = $MBI->_zero();
168 $self->{_es} = '+';
169 $self->{sign} = $1 || '+';
170 $self->{_m} = $MBI->_new($2);
171 return $self->round(@r) if !$downgrade;
172 }
173
174 my ($mis,$miv,$mfv,$es,$ev) = Math::BigInt::_split($wanted);
175 if (!ref $mis)
176 {
177 if ($_trap_nan)
178 {
179 require Carp;
180 Carp::croak ("$wanted is not a number initialized to $class");
181 }
182
183 return $downgrade->bnan() if $downgrade;
184
185 $self->{_e} = $MBI->_zero();
186 $self->{_es} = '+';
187 $self->{_m} = $MBI->_zero();
188 $self->{sign} = $nan;
189 }
190 else
191 {
192 # make integer from mantissa by adjusting exp, then convert to int
193 $self->{_e} = $MBI->_new($$ev); # exponent
194 $self->{_es} = $$es || '+';
195 my $mantissa = "$$miv$$mfv"; # create mant.
196 $mantissa =~ s/^0+(\d)/$1/; # strip leading zeros
197 $self->{_m} = $MBI->_new($mantissa); # create mant.
198
199 # 3.123E0 = 3123E-3, and 3.123E-2 => 3123E-5
200 if (CORE::length($$mfv) != 0)
201 {
202 my $len = $MBI->_new( CORE::length($$mfv));
203 ($self->{_e}, $self->{_es}) =
204 _e_sub ($self->{_e}, $len, $self->{_es}, '+');
205 }
206 # we can only have trailing zeros on the mantissa if $$mfv eq ''
207 else
208 {
209 # Use a regexp to count the trailing zeros in $$miv instead of _zeros()
210 # because that is faster, especially when _m is not stored in base 10.
211 my $zeros = 0; $zeros = CORE::length($1) if $$miv =~ /[1-9](0*)$/;
212 if ($zeros != 0)
213 {
214 my $z = $MBI->_new($zeros);
215 # turn '120e2' into '12e3'
216 $MBI->_rsft ( $self->{_m}, $z, 10);
217 ($self->{_e}, $self->{_es}) =
218 _e_add ( $self->{_e}, $z, $self->{_es}, '+');
219 }
220 }
221 $self->{sign} = $$mis;
222
223 # for something like 0Ey, set y to 1, and -0 => +0
224 # Check $$miv for being '0' and $$mfv eq '', because otherwise _m could not
225 # have become 0. That's faster than to call $MBI->_is_zero().
226 $self->{sign} = '+', $self->{_e} = $MBI->_one()
227 if $$miv eq '0' and $$mfv eq '';
228
229 return $self->round(@r) if !$downgrade;
230 }
231 # if downgrade, inf, NaN or integers go down
232
233 if ($downgrade && $self->{_es} eq '+')
234 {
235 if ($MBI->_is_zero( $self->{_e} ))
236 {
237 return $downgrade->new($$mis . $MBI->_str( $self->{_m} ));
238 }
239 return $downgrade->new($self->bsstr());
240 }
241 $self->bnorm()->round(@r); # first normalize, then round
242 }
243
244sub copy
245 {
246 # if two arguments, the first one is the class to "swallow" subclasses
247 if (@_ > 1)
248 {
249 my $self = bless {
250 sign => $_[1]->{sign},
251 _es => $_[1]->{_es},
252 _m => $MBI->_copy($_[1]->{_m}),
253 _e => $MBI->_copy($_[1]->{_e}),
254 }, $_[0] if @_ > 1;
255
256 $self->{_a} = $_[1]->{_a} if defined $_[1]->{_a};
257 $self->{_p} = $_[1]->{_p} if defined $_[1]->{_p};
258 return $self;
259 }
260
261 my $self = bless {
262 sign => $_[0]->{sign},
263 _es => $_[0]->{_es},
264 _m => $MBI->_copy($_[0]->{_m}),
265 _e => $MBI->_copy($_[0]->{_e}),
266 }, ref($_[0]);
267
268 $self->{_a} = $_[0]->{_a} if defined $_[0]->{_a};
269 $self->{_p} = $_[0]->{_p} if defined $_[0]->{_p};
270 $self;
271 }
272
273sub _bnan
274 {
275 # used by parent class bone() to initialize number to NaN
276 my $self = shift;
277
278 if ($_trap_nan)
279 {
280 require Carp;
281 my $class = ref($self);
282 Carp::croak ("Tried to set $self to NaN in $class\::_bnan()");
283 }
284
285 $IMPORT=1; # call our import only once
286 $self->{_m} = $MBI->_zero();
287 $self->{_e} = $MBI->_zero();
288 $self->{_es} = '+';
289 }
290
291sub _binf
292 {
293 # used by parent class bone() to initialize number to +-inf
294 my $self = shift;
295
296 if ($_trap_inf)
297 {
298 require Carp;
299 my $class = ref($self);
300 Carp::croak ("Tried to set $self to +-inf in $class\::_binf()");
301 }
302
303 $IMPORT=1; # call our import only once
304 $self->{_m} = $MBI->_zero();
305 $self->{_e} = $MBI->_zero();
306 $self->{_es} = '+';
307 }
308
309sub _bone
310 {
311 # used by parent class bone() to initialize number to 1
312 my $self = shift;
313 $IMPORT=1; # call our import only once
314 $self->{_m} = $MBI->_one();
315 $self->{_e} = $MBI->_zero();
316 $self->{_es} = '+';
317 }
318
319sub _bzero
320 {
321 # used by parent class bone() to initialize number to 0
322 my $self = shift;
323 $IMPORT=1; # call our import only once
324 $self->{_m} = $MBI->_zero();
325 $self->{_e} = $MBI->_one();
326 $self->{_es} = '+';
327 }
328
329sub isa
330 {
331 my ($self,$class) = @_;
332 return if $class =~ /^Math::BigInt/; # we aren't one of these
333 UNIVERSAL::isa($self,$class);
334 }
335
336sub config
337 {
338 # return (later set?) configuration data as hash ref
339 my $class = shift || 'Math::BigFloat';
340
341 if (@_ == 1 && ref($_[0]) ne 'HASH')
342 {
343 my $cfg = $class->SUPER::config();
344 return $cfg->{$_[0]};
345 }
346
347 my $cfg = $class->SUPER::config(@_);
348
349 # now we need only to override the ones that are different from our parent
350 $cfg->{class} = $class;
351 $cfg->{with} = $MBI;
352 $cfg;
353 }
354
355##############################################################################
356# string conversion
357
358sub bstr
359 {
360 # (ref to BFLOAT or num_str ) return num_str
361 # Convert number from internal format to (non-scientific) string format.
362 # internal format is always normalized (no leading zeros, "-0" => "+0")
363 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
364
365 if ($x->{sign} !~ /^[+-]$/)
366 {
367 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
368 return 'inf'; # +inf
369 }
370
371 my $es = '0'; my $len = 1; my $cad = 0; my $dot = '.';
372
373 # $x is zero?
374 my $not_zero = !($x->{sign} eq '+' && $MBI->_is_zero($x->{_m}));
375 if ($not_zero)
376 {
377 $es = $MBI->_str($x->{_m});
378 $len = CORE::length($es);
379 my $e = $MBI->_num($x->{_e});
380 $e = -$e if $x->{_es} eq '-';
381 if ($e < 0)
382 {
383 $dot = '';
384 # if _e is bigger than a scalar, the following will blow your memory
385 if ($e <= -$len)
386 {
387 my $r = abs($e) - $len;
388 $es = '0.'. ('0' x $r) . $es; $cad = -($len+$r);
389 }
390 else
391 {
392 substr($es,$e,0) = '.'; $cad = $MBI->_num($x->{_e});
393 $cad = -$cad if $x->{_es} eq '-';
394 }
395 }
396 elsif ($e > 0)
397 {
398 # expand with zeros
399 $es .= '0' x $e; $len += $e; $cad = 0;
400 }
401 } # if not zero
402
403 $es = '-'.$es if $x->{sign} eq '-';
404 # if set accuracy or precision, pad with zeros on the right side
405 if ((defined $x->{_a}) && ($not_zero))
406 {
407 # 123400 => 6, 0.1234 => 4, 0.001234 => 4
408 my $zeros = $x->{_a} - $cad; # cad == 0 => 12340
409 $zeros = $x->{_a} - $len if $cad != $len;
410 $es .= $dot.'0' x $zeros if $zeros > 0;
411 }
412 elsif ((($x->{_p} || 0) < 0))
413 {
414 # 123400 => 6, 0.1234 => 4, 0.001234 => 6
415 my $zeros = -$x->{_p} + $cad;
416 $es .= $dot.'0' x $zeros if $zeros > 0;
417 }
418 $es;
419 }
420
421sub bsstr
422 {
423 # (ref to BFLOAT or num_str ) return num_str
424 # Convert number from internal format to scientific string format.
425 # internal format is always normalized (no leading zeros, "-0E0" => "+0E0")
426 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
427
428 if ($x->{sign} !~ /^[+-]$/)
429 {
430 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
431 return 'inf'; # +inf
432 }
433 my $sep = 'e'.$x->{_es};
434 my $sign = $x->{sign}; $sign = '' if $sign eq '+';
435 $sign . $MBI->_str($x->{_m}) . $sep . $MBI->_str($x->{_e});
436 }
437
438sub numify
439 {
440 # Convert a Perl scalar number from a BigFloat object.
441 # Create a string and let Perl's atoi()/atof() handle the rest.
442 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
443 return 0 + $x->bsstr();
444 }
445
446##############################################################################
447# public stuff (usually prefixed with "b")
448
449sub bneg
450 {
451 # (BINT or num_str) return BINT
452 # negate number or make a negated number from string
453 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
454
455 return $x if $x->modify('bneg');
456
457 # for +0 do not negate (to have always normalized +0). Does nothing for 'NaN'
458 $x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $MBI->_is_zero($x->{_m}));
459 $x;
460 }
461
462# tels 2001-08-04
463# XXX TODO this must be overwritten and return NaN for non-integer values
464# band(), bior(), bxor(), too
465#sub bnot
466# {
467# $class->SUPER::bnot($class,@_);
468# }
469
470sub bcmp
471 {
472 # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
473
474 # set up parameters
475 my ($self,$x,$y) = (ref($_[0]),@_);
476
477 # objectify is costly, so avoid it
478 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
479 {
480 ($self,$x,$y) = objectify(2,@_);
481 }
482
483 return $upgrade->bcmp($x,$y) if defined $upgrade &&
484 ((!$x->isa($self)) || (!$y->isa($self)));
485
486 # Handle all 'nan' cases.
487
488 return undef if ($x->{sign} eq $nan) || ($y->{sign} eq $nan);
489
490 # Handle all '+inf' and '-inf' cases.
491
492 return 0 if ($x->{sign} eq '+inf' && $y->{sign} eq '+inf' ||
493 $x->{sign} eq '-inf' && $y->{sign} eq '-inf');
494 return +1 if $x->{sign} eq '+inf'; # x = +inf and y < +inf
495 return -1 if $x->{sign} eq '-inf'; # x = -inf and y > -inf
496 return -1 if $y->{sign} eq '+inf'; # x < +inf and y = +inf
497 return +1 if $y->{sign} eq '-inf'; # x > -inf and y = -inf
498
499 # Handle all cases with opposite signs.
500
501 return +1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # also does 0 <=> -y
502 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # also does -x <=> 0
503
504 # Handle all remaining zero cases.
505
506 my $xz = $x->is_zero();
507 my $yz = $y->is_zero();
508 return 0 if $xz && $yz; # 0 <=> 0
509 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
510 return +1 if $yz && $x->{sign} eq '+'; # +x <=> 0
511
512 # Both arguments are now finite, non-zero numbers with the same sign.
513
514 my $cmp;
515
516 # The next step is to compare the exponents, but since each mantissa is an
517 # integer of arbitrary value, the exponents must be normalized by the length
518 # of the mantissas before we can compare them.
519
520 my $mxl = $MBI->_len($x->{_m});
521 my $myl = $MBI->_len($y->{_m});
522
523 # If the mantissas have the same length, there is no point in normalizing the
524 # exponents by the length of the mantissas, so treat that as a special case.
525
526 if ($mxl == $myl) {
527
528 # First handle the two cases where the exponents have different signs.
529
530 if ($x->{_es} eq '+' && $y->{_es} eq '-') {
531 $cmp = +1;
532 }
533
534 elsif ($x->{_es} eq '-' && $y->{_es} eq '+') {
535 $cmp = -1;
536 }
537
538 # Then handle the case where the exponents have the same sign.
539
540 else {
541 $cmp = $MBI->_acmp($x->{_e}, $y->{_e});
542 $cmp = -$cmp if $x->{_es} eq '-';
543 }
544
545 # Adjust for the sign, which is the same for x and y, and bail out if
546 # we're done.
547
548 $cmp = -$cmp if $x->{sign} eq '-'; # 124 > 123, but -124 < -123
549 return $cmp if $cmp;
550
551 }
552
553 # We must normalize each exponent by the length of the corresponding
554 # mantissa. Life is a lot easier if we first make both exponents
555 # non-negative. We do this by adding the same positive value to both
556 # exponent. This is safe, because when comparing the exponents, only the
557 # relative difference is important.
558
559 my $ex;
560 my $ey;
561
562 if ($x->{_es} eq '+') {
563
564 # If the exponent of x is >= 0 and the exponent of y is >= 0, there is no
565 # need to do anything special.
566
567 if ($y->{_es} eq '+') {
568 $ex = $MBI->_copy($x->{_e});
569 $ey = $MBI->_copy($y->{_e});
570 }
571
572 # If the exponent of x is >= 0 and the exponent of y is < 0, add the
573 # absolute value of the exponent of y to both.
574
575 else {
576 $ex = $MBI->_copy($x->{_e});
577 $ex = $MBI->_add($ex, $y->{_e}); # ex + |ey|
578 $ey = $MBI->_zero(); # -ex + |ey| = 0
579 }
580
581 } else {
582
583 # If the exponent of x is < 0 and the exponent of y is >= 0, add the
584 # absolute value of the exponent of x to both.
585
586 if ($y->{_es} eq '+') {
587 $ex = $MBI->_zero(); # -ex + |ex| = 0
588 $ey = $MBI->_copy($y->{_e});
589 $ey = $MBI->_add($ey, $x->{_e}); # ey + |ex|
590 }
591
592 # If the exponent of x is < 0 and the exponent of y is < 0, add the
593 # absolute values of both exponents to both exponents.
594
595 else {
596 $ex = $MBI->_copy($y->{_e}); # -ex + |ey| + |ex| = |ey|
597 $ey = $MBI->_copy($x->{_e}); # -ey + |ex| + |ey| = |ex|
598 }
599
600 }
601
602 # Now we can normalize the exponents by adding lengths of the mantissas.
603
604 $MBI->_add($ex, $MBI->_new($mxl));
605 $MBI->_add($ey, $MBI->_new($myl));
606
607 # We're done if the exponents are different.
608
609 $cmp = $MBI->_acmp($ex, $ey);
610 $cmp = -$cmp if $x->{sign} eq '-'; # 124 > 123, but -124 < -123
611 return $cmp if $cmp;
612
613 # Compare the mantissas, but first normalize them by padding the shorter
614 # mantissa with zeros (shift left) until it has the same length as the longer
615 # mantissa.
616
617 my $mx = $x->{_m};
618 my $my = $y->{_m};
619
620 if ($mxl > $myl) {
621 $my = $MBI->_lsft($MBI->_copy($my), $MBI->_new($mxl - $myl), 10);
622 } elsif ($mxl < $myl) {
623 $mx = $MBI->_lsft($MBI->_copy($mx), $MBI->_new($myl - $mxl), 10);
624 }
625
626 $cmp = $MBI->_acmp($mx, $my);
627 $cmp = -$cmp if $x->{sign} eq '-'; # 124 > 123, but -124 < -123
628 return $cmp;
629
630 }
631
632sub bacmp
633 {
634 # Compares 2 values, ignoring their signs.
635 # Returns one of undef, <0, =0, >0. (suitable for sort)
636
637 # set up parameters
638 my ($self,$x,$y) = (ref($_[0]),@_);
639 # objectify is costly, so avoid it
640 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
641 {
642 ($self,$x,$y) = objectify(2,@_);
643 }
644
645 return $upgrade->bacmp($x,$y) if defined $upgrade &&
646 ((!$x->isa($self)) || (!$y->isa($self)));
647
648 # handle +-inf and NaN's
649 if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/)
650 {
651 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
652 return 0 if ($x->is_inf() && $y->is_inf());
653 return 1 if ($x->is_inf() && !$y->is_inf());
654 return -1;
655 }
656
657 # shortcut
658 my $xz = $x->is_zero();
659 my $yz = $y->is_zero();
660 return 0 if $xz && $yz; # 0 <=> 0
661 return -1 if $xz && !$yz; # 0 <=> +y
662 return 1 if $yz && !$xz; # +x <=> 0
663
664 # adjust so that exponents are equal
665 my $lxm = $MBI->_len($x->{_m});
666 my $lym = $MBI->_len($y->{_m});
667 my ($xes,$yes) = (1,1);
668 $xes = -1 if $x->{_es} ne '+';
669 $yes = -1 if $y->{_es} ne '+';
670 # the numify somewhat limits our length, but makes it much faster
671 my $lx = $lxm + $xes * $MBI->_num($x->{_e});
672 my $ly = $lym + $yes * $MBI->_num($y->{_e});
673 my $l = $lx - $ly;
674 return $l <=> 0 if $l != 0;
675
676 # lengths (corrected by exponent) are equal
677 # so make mantissa equal-length by padding with zero (shift left)
678 my $diff = $lxm - $lym;
679 my $xm = $x->{_m}; # not yet copy it
680 my $ym = $y->{_m};
681 if ($diff > 0)
682 {
683 $ym = $MBI->_copy($y->{_m});
684 $ym = $MBI->_lsft($ym, $MBI->_new($diff), 10);
685 }
686 elsif ($diff < 0)
687 {
688 $xm = $MBI->_copy($x->{_m});
689 $xm = $MBI->_lsft($xm, $MBI->_new(-$diff), 10);
690 }
691 $MBI->_acmp($xm,$ym);
692 }
693
694sub badd
695 {
696 # add second arg (BFLOAT or string) to first (BFLOAT) (modifies first)
697 # return result as BFLOAT
698
699 # set up parameters
700 my ($self,$x,$y,@r) = (ref($_[0]),@_);
701 # objectify is costly, so avoid it
702 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
703 {
704 ($self,$x,$y,@r) = objectify(2,@_);
705 }
706
707 return $x if $x->modify('badd');
708
709 # inf and NaN handling
710 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
711 {
712 # NaN first
713 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
714 # inf handling
715 if (($x->{sign} =~ /^[+-]inf$/) && ($y->{sign} =~ /^[+-]inf$/))
716 {
717 # +inf++inf or -inf+-inf => same, rest is NaN
718 return $x if $x->{sign} eq $y->{sign};
719 return $x->bnan();
720 }
721 # +-inf + something => +inf; something +-inf => +-inf
722 $x->{sign} = $y->{sign}, return $x if $y->{sign} =~ /^[+-]inf$/;
723 return $x;
724 }
725
726 return $upgrade->badd($x,$y,@r) if defined $upgrade &&
727 ((!$x->isa($self)) || (!$y->isa($self)));
728
729 $r[3] = $y; # no push!
730
731 # speed: no add for 0+y or x+0
732 return $x->bround(@r) if $y->is_zero(); # x+0
733 if ($x->is_zero()) # 0+y
734 {
735 # make copy, clobbering up x (modify in place!)
736 $x->{_e} = $MBI->_copy($y->{_e});
737 $x->{_es} = $y->{_es};
738 $x->{_m} = $MBI->_copy($y->{_m});
739 $x->{sign} = $y->{sign} || $nan;
740 return $x->round(@r);
741 }
742
743 # take lower of the two e's and adapt m1 to it to match m2
744 my $e = $y->{_e};
745 $e = $MBI->_zero() if !defined $e; # if no BFLOAT?
746 $e = $MBI->_copy($e); # make copy (didn't do it yet)
747
748 my $es;
749
750 ($e,$es) = _e_sub($e, $x->{_e}, $y->{_es} || '+', $x->{_es});
751
752 my $add = $MBI->_copy($y->{_m});
753
754 if ($es eq '-') # < 0
755 {
756 $MBI->_lsft( $x->{_m}, $e, 10);
757 ($x->{_e},$x->{_es}) = _e_add($x->{_e}, $e, $x->{_es}, $es);
758 }
759 elsif (!$MBI->_is_zero($e)) # > 0
760 {
761 $MBI->_lsft($add, $e, 10);
762 }
763 # else: both e are the same, so just leave them
764
765 if ($x->{sign} eq $y->{sign})
766 {
767 # add
768 $x->{_m} = $MBI->_add($x->{_m}, $add);
769 }
770 else
771 {
772 ($x->{_m}, $x->{sign}) =
773 _e_add($x->{_m}, $add, $x->{sign}, $y->{sign});
774 }
775
776 # delete trailing zeros, then round
777 $x->bnorm()->round(@r);
778 }
779
780# sub bsub is inherited from Math::BigInt!
781
782sub binc
783 {
784 # increment arg by one
785 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
786
787 return $x if $x->modify('binc');
788
789 if ($x->{_es} eq '-')
790 {
791 return $x->badd($self->bone(),@r); # digits after dot
792 }
793
794 if (!$MBI->_is_zero($x->{_e})) # _e == 0 for NaN, inf, -inf
795 {
796 # 1e2 => 100, so after the shift below _m has a '0' as last digit
797 $x->{_m} = $MBI->_lsft($x->{_m}, $x->{_e},10); # 1e2 => 100
798 $x->{_e} = $MBI->_zero(); # normalize
799 $x->{_es} = '+';
800 # we know that the last digit of $x will be '1' or '9', depending on the
801 # sign
802 }
803 # now $x->{_e} == 0
804 if ($x->{sign} eq '+')
805 {
806 $MBI->_inc($x->{_m});
807 return $x->bnorm()->bround(@r);
808 }
809 elsif ($x->{sign} eq '-')
810 {
811 $MBI->_dec($x->{_m});
812 $x->{sign} = '+' if $MBI->_is_zero($x->{_m}); # -1 +1 => -0 => +0
813 return $x->bnorm()->bround(@r);
814 }
815 # inf, nan handling etc
816 $x->badd($self->bone(),@r); # badd() does round
817 }
818
819sub bdec
820 {
821 # decrement arg by one
822 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
823
824 return $x if $x->modify('bdec');
825
826 if ($x->{_es} eq '-')
827 {
828 return $x->badd($self->bone('-'),@r); # digits after dot
829 }
830
831 if (!$MBI->_is_zero($x->{_e}))
832 {
833 $x->{_m} = $MBI->_lsft($x->{_m}, $x->{_e},10); # 1e2 => 100
834 $x->{_e} = $MBI->_zero(); # normalize
835 $x->{_es} = '+';
836 }
837 # now $x->{_e} == 0
838 my $zero = $x->is_zero();
839 # <= 0
840 if (($x->{sign} eq '-') || $zero)
841 {
842 $MBI->_inc($x->{_m});
843 $x->{sign} = '-' if $zero; # 0 => 1 => -1
844 $x->{sign} = '+' if $MBI->_is_zero($x->{_m}); # -1 +1 => -0 => +0
845 return $x->bnorm()->round(@r);
846 }
847 # > 0
848 elsif ($x->{sign} eq '+')
849 {
850 $MBI->_dec($x->{_m});
851 return $x->bnorm()->round(@r);
852 }
853 # inf, nan handling etc
854 $x->badd($self->bone('-'),@r); # does round
855 }
856
857sub DEBUG () { 0; }
858
859sub blog
860 {
861 my ($self,$x,$base,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
862
863 return $x if $x->modify('blog');
864
865 # $base > 0, $base != 1; if $base == undef default to $base == e
866 # $x >= 0
867
868 # we need to limit the accuracy to protect against overflow
869 my $fallback = 0;
870 my ($scale,@params);
871 ($x,@params) = $x->_find_round_parameters($a,$p,$r);
872
873 # also takes care of the "error in _find_round_parameters?" case
874 return $x->bnan() if $x->{sign} ne '+' || $x->is_zero();
875
876 # no rounding at all, so must use fallback
877 if (scalar @params == 0)
878 {
879 # simulate old behaviour
880 $params[0] = $self->div_scale(); # and round to it as accuracy
881 $params[1] = undef; # P = undef
882 $scale = $params[0]+4; # at least four more for proper round
883 $params[2] = $r; # round mode by caller or undef
884 $fallback = 1; # to clear a/p afterwards
885 }
886 else
887 {
888 # the 4 below is empirical, and there might be cases where it is not
889 # enough...
890 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
891 }
892
893 return $x->bzero(@params) if $x->is_one();
894 # base not defined => base == Euler's number e
895 if (defined $base)
896 {
897 # make object, since we don't feed it through objectify() to still get the
898 # case of $base == undef
899 $base = $self->new($base) unless ref($base);
900 # $base > 0; $base != 1
901 return $x->bnan() if $base->is_zero() || $base->is_one() ||
902 $base->{sign} ne '+';
903 # if $x == $base, we know the result must be 1.0
904 if ($x->bcmp($base) == 0)
905 {
906 $x->bone('+',@params);
907 if ($fallback)
908 {
909 # clear a/p after round, since user did not request it
910 delete $x->{_a}; delete $x->{_p};
911 }
912 return $x;
913 }
914 }
915
916 # when user set globals, they would interfere with our calculation, so
917 # disable them and later re-enable them
918 no strict 'refs';
919 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
920 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
921 # we also need to disable any set A or P on $x (_find_round_parameters took
922 # them already into account), since these would interfere, too
923 delete $x->{_a}; delete $x->{_p};
924 # need to disable $upgrade in BigInt, to avoid deep recursion
925 local $Math::BigInt::upgrade = undef;
926 local $Math::BigFloat::downgrade = undef;
927
928 # upgrade $x if $x is not a BigFloat (handle BigInt input)
929 # XXX TODO: rebless!
930 if (!$x->isa('Math::BigFloat'))
931 {
932 $x = Math::BigFloat->new($x);
933 $self = ref($x);
934 }
935
936 my $done = 0;
937
938 # If the base is defined and an integer, try to calculate integer result
939 # first. This is very fast, and in case the real result was found, we can
940 # stop right here.
941 if (defined $base && $base->is_int() && $x->is_int())
942 {
943 my $i = $MBI->_copy( $x->{_m} );
944 $MBI->_lsft( $i, $x->{_e}, 10 ) unless $MBI->_is_zero($x->{_e});
945 my $int = Math::BigInt->bzero();
946 $int->{value} = $i;
947 $int->blog($base->as_number());
948 # if ($exact)
949 if ($base->as_number()->bpow($int) == $x)
950 {
951 # found result, return it
952 $x->{_m} = $int->{value};
953 $x->{_e} = $MBI->_zero();
954 $x->{_es} = '+';
955 $x->bnorm();
956 $done = 1;
957 }
958 }
959
960 if ($done == 0)
961 {
962 # base is undef, so base should be e (Euler's number), so first calculate the
963 # log to base e (using reduction by 10 (and probably 2)):
964 $self->_log_10($x,$scale);
965
966 # and if a different base was requested, convert it
967 if (defined $base)
968 {
969 $base = Math::BigFloat->new($base) unless $base->isa('Math::BigFloat');
970 # not ln, but some other base (don't modify $base)
971 $x->bdiv( $base->copy()->blog(undef,$scale), $scale );
972 }
973 }
974
975 # shortcut to not run through _find_round_parameters again
976 if (defined $params[0])
977 {
978 $x->bround($params[0],$params[2]); # then round accordingly
979 }
980 else
981 {
982 $x->bfround($params[1],$params[2]); # then round accordingly
983 }
984 if ($fallback)
985 {
986 # clear a/p after round, since user did not request it
987 delete $x->{_a}; delete $x->{_p};
988 }
989 # restore globals
990 $$abr = $ab; $$pbr = $pb;
991
992 $x;
993 }
994
995sub _len_to_steps
996 {
997 # Given D (digits in decimal), compute N so that N! (N factorial) is
998 # at least D digits long. D should be at least 50.
999 my $d = shift;
1000
1001 # two constants for the Ramanujan estimate of ln(N!)
1002 my $lg2 = log(2 * 3.14159265) / 2;
1003 my $lg10 = log(10);
1004
1005 # D = 50 => N => 42, so L = 40 and R = 50
1006 my $l = 40; my $r = $d;
1007
1008 # Otherwise this does not work under -Mbignum and we do not yet have "no bignum;" :(
1009 $l = $l->numify if ref($l);
1010 $r = $r->numify if ref($r);
1011 $lg2 = $lg2->numify if ref($lg2);
1012 $lg10 = $lg10->numify if ref($lg10);
1013
1014 # binary search for the right value (could this be written as the reverse of lg(n!)?)
1015 while ($r - $l > 1)
1016 {
1017 my $n = int(($r - $l) / 2) + $l;
1018 my $ramanujan =
1019 int(($n * log($n) - $n + log( $n * (1 + 4*$n*(1+2*$n)) ) / 6 + $lg2) / $lg10);
1020 $ramanujan > $d ? $r = $n : $l = $n;
1021 }
1022 $l;
1023 }
1024
1025sub bnok
1026 {
1027 # Calculate n over k (binomial coefficient or "choose" function) as integer.
1028 # set up parameters
1029 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1030
1031 # objectify is costly, so avoid it
1032 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1033 {
1034 ($self,$x,$y,@r) = objectify(2,@_);
1035 }
1036
1037 return $x if $x->modify('bnok');
1038
1039 return $x->bnan() if $x->is_nan() || $y->is_nan();
1040 return $x->binf() if $x->is_inf();
1041
1042 my $u = $x->as_int();
1043 $u->bnok($y->as_int());
1044
1045 $x->{_m} = $u->{value};
1046 $x->{_e} = $MBI->_zero();
1047 $x->{_es} = '+';
1048 $x->{sign} = '+';
1049 $x->bnorm(@r);
1050 }
1051
1052sub bexp
1053 {
1054 # Calculate e ** X (Euler's number to the power of X)
1055 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1056
1057 return $x if $x->modify('bexp');
1058
1059 return $x->binf() if $x->{sign} eq '+inf';
1060 return $x->bzero() if $x->{sign} eq '-inf';
1061
1062 # we need to limit the accuracy to protect against overflow
1063 my $fallback = 0;
1064 my ($scale,@params);
1065 ($x,@params) = $x->_find_round_parameters($a,$p,$r);
1066
1067 # also takes care of the "error in _find_round_parameters?" case
1068 return $x if $x->{sign} eq 'NaN';
1069
1070 # no rounding at all, so must use fallback
1071 if (scalar @params == 0)
1072 {
1073 # simulate old behaviour
1074 $params[0] = $self->div_scale(); # and round to it as accuracy
1075 $params[1] = undef; # P = undef
1076 $scale = $params[0]+4; # at least four more for proper round
1077 $params[2] = $r; # round mode by caller or undef
1078 $fallback = 1; # to clear a/p afterwards
1079 }
1080 else
1081 {
1082 # the 4 below is empirical, and there might be cases where it's not enough...
1083 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
1084 }
1085
1086 return $x->bone(@params) if $x->is_zero();
1087
1088 if (!$x->isa('Math::BigFloat'))
1089 {
1090 $x = Math::BigFloat->new($x);
1091 $self = ref($x);
1092 }
1093
1094 # when user set globals, they would interfere with our calculation, so
1095 # disable them and later re-enable them
1096 no strict 'refs';
1097 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
1098 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
1099 # we also need to disable any set A or P on $x (_find_round_parameters took
1100 # them already into account), since these would interfere, too
1101 delete $x->{_a}; delete $x->{_p};
1102 # need to disable $upgrade in BigInt, to avoid deep recursion
1103 local $Math::BigInt::upgrade = undef;
1104 local $Math::BigFloat::downgrade = undef;
1105
1106 my $x_org = $x->copy();
1107
1108 # We use the following Taylor series:
1109
1110 # x x^2 x^3 x^4
1111 # e = 1 + --- + --- + --- + --- ...
1112 # 1! 2! 3! 4!
1113
1114 # The difference for each term is X and N, which would result in:
1115 # 2 copy, 2 mul, 2 add, 1 inc, 1 div operations per term
1116
1117 # But it is faster to compute exp(1) and then raising it to the
1118 # given power, esp. if $x is really big and an integer because:
1119
1120 # * The numerator is always 1, making the computation faster
1121 # * the series converges faster in the case of x == 1
1122 # * We can also easily check when we have reached our limit: when the
1123 # term to be added is smaller than "1E$scale", we can stop - f.i.
1124 # scale == 5, and we have 1/40320, then we stop since 1/40320 < 1E-5.
1125 # * we can compute the *exact* result by simulating bigrat math:
1126
1127 # 1 1 gcd(3,4) = 1 1*24 + 1*6 5
1128 # - + - = ---------- = --
1129 # 6 24 6*24 24
1130
1131 # We do not compute the gcd() here, but simple do:
1132 # 1 1 1*24 + 1*6 30
1133 # - + - = --------- = --
1134 # 6 24 6*24 144
1135
1136 # In general:
1137 # a c a*d + c*b and note that c is always 1 and d = (b*f)
1138 # - + - = ---------
1139 # b d b*d
1140
1141 # This leads to: which can be reduced by b to:
1142 # a 1 a*b*f + b a*f + 1
1143 # - + - = --------- = -------
1144 # b b*f b*b*f b*f
1145
1146 # The first terms in the series are:
1147
1148 # 1 1 1 1 1 1 1 1 13700
1149 # -- + -- + -- + -- + -- + --- + --- + ---- = -----
1150 # 1 1 2 6 24 120 720 5040 5040
1151
1152 # Note that we cannot simple reduce 13700/5040 to 685/252, but must keep A and B!
1153
1154 if ($scale <= 75)
1155 {
1156 # set $x directly from a cached string form
1157 $x->{_m} = $MBI->_new(
1158 "27182818284590452353602874713526624977572470936999595749669676277240766303535476");
1159 $x->{sign} = '+';
1160 $x->{_es} = '-';
1161 $x->{_e} = $MBI->_new(79);
1162 }
1163 else
1164 {
1165 # compute A and B so that e = A / B.
1166
1167 # After some terms we end up with this, so we use it as a starting point:
1168 my $A = $MBI->_new("90933395208605785401971970164779391644753259799242");
1169 my $F = $MBI->_new(42); my $step = 42;
1170
1171 # Compute how many steps we need to take to get $A and $B sufficiently big
1172 my $steps = _len_to_steps($scale - 4);
1173# print STDERR "# Doing $steps steps for ", $scale-4, " digits\n";
1174 while ($step++ <= $steps)
1175 {
1176 # calculate $a * $f + 1
1177 $A = $MBI->_mul($A, $F);
1178 $A = $MBI->_inc($A);
1179 # increment f
1180 $F = $MBI->_inc($F);
1181 }
1182 # compute $B as factorial of $steps (this is faster than doing it manually)
1183 my $B = $MBI->_fac($MBI->_new($steps));
1184
1185# print "A ", $MBI->_str($A), "\nB ", $MBI->_str($B), "\n";
1186
1187 # compute A/B with $scale digits in the result (truncate, not round)
1188 $A = $MBI->_lsft( $A, $MBI->_new($scale), 10);
1189 $A = $MBI->_div( $A, $B );
1190
1191 $x->{_m} = $A;
1192 $x->{sign} = '+';
1193 $x->{_es} = '-';
1194 $x->{_e} = $MBI->_new($scale);
1195 }
1196
1197 # $x contains now an estimate of e, with some surplus digits, so we can round
1198 if (!$x_org->is_one())
1199 {
1200 # raise $x to the wanted power and round it in one step:
1201 $x->bpow($x_org, @params);
1202 }
1203 else
1204 {
1205 # else just round the already computed result
1206 delete $x->{_a}; delete $x->{_p};
1207 # shortcut to not run through _find_round_parameters again
1208 if (defined $params[0])
1209 {
1210 $x->bround($params[0],$params[2]); # then round accordingly
1211 }
1212 else
1213 {
1214 $x->bfround($params[1],$params[2]); # then round accordingly
1215 }
1216 }
1217 if ($fallback)
1218 {
1219 # clear a/p after round, since user did not request it
1220 delete $x->{_a}; delete $x->{_p};
1221 }
1222 # restore globals
1223 $$abr = $ab; $$pbr = $pb;
1224
1225 $x; # return modified $x
1226 }
1227
1228sub _log
1229 {
1230 # internal log function to calculate ln() based on Taylor series.
1231 # Modifies $x in place.
1232 my ($self,$x,$scale) = @_;
1233
1234 # in case of $x == 1, result is 0
1235 return $x->bzero() if $x->is_one();
1236
1237 # XXX TODO: rewrite this in a similar manner to bexp()
1238
1239 # http://www.efunda.com/math/taylor_series/logarithmic.cfm?search_string=log
1240
1241 # u = x-1, v = x+1
1242 # _ _
1243 # Taylor: | u 1 u^3 1 u^5 |
1244 # ln (x) = 2 | --- + - * --- + - * --- + ... | x > 0
1245 # |_ v 3 v^3 5 v^5 _|
1246
1247 # This takes much more steps to calculate the result and is thus not used
1248 # u = x-1
1249 # _ _
1250 # Taylor: | u 1 u^2 1 u^3 |
1251 # ln (x) = 2 | --- + - * --- + - * --- + ... | x > 1/2
1252 # |_ x 2 x^2 3 x^3 _|
1253
1254 my ($limit,$v,$u,$below,$factor,$two,$next,$over,$f);
1255
1256 $v = $x->copy(); $v->binc(); # v = x+1
1257 $x->bdec(); $u = $x->copy(); # u = x-1; x = x-1
1258 $x->bdiv($v,$scale); # first term: u/v
1259 $below = $v->copy();
1260 $over = $u->copy();
1261 $u *= $u; $v *= $v; # u^2, v^2
1262 $below->bmul($v); # u^3, v^3
1263 $over->bmul($u);
1264 $factor = $self->new(3); $f = $self->new(2);
1265
1266 my $steps = 0 if DEBUG;
1267 $limit = $self->new("1E-". ($scale-1));
1268 while (3 < 5)
1269 {
1270 # we calculate the next term, and add it to the last
1271 # when the next term is below our limit, it won't affect the outcome
1272 # anymore, so we stop
1273
1274 # calculating the next term simple from over/below will result in quite
1275 # a time hog if the input has many digits, since over and below will
1276 # accumulate more and more digits, and the result will also have many
1277 # digits, but in the end it is rounded to $scale digits anyway. So if we
1278 # round $over and $below first, we save a lot of time for the division
1279 # (not with log(1.2345), but try log (123**123) to see what I mean. This
1280 # can introduce a rounding error if the division result would be f.i.
1281 # 0.1234500000001 and we round it to 5 digits it would become 0.12346, but
1282 # if we truncated $over and $below we might get 0.12345. Does this matter
1283 # for the end result? So we give $over and $below 4 more digits to be
1284 # on the safe side (unscientific error handling as usual... :+D
1285
1286 $next = $over->copy->bround($scale+4)->bdiv(
1287 $below->copy->bmul($factor)->bround($scale+4),
1288 $scale);
1289
1290## old version:
1291## $next = $over->copy()->bdiv($below->copy()->bmul($factor),$scale);
1292
1293 last if $next->bacmp($limit) <= 0;
1294
1295 delete $next->{_a}; delete $next->{_p};
1296 $x->badd($next);
1297 # calculate things for the next term
1298 $over *= $u; $below *= $v; $factor->badd($f);
1299 if (DEBUG)
1300 {
1301 $steps++; print "step $steps = $x\n" if $steps % 10 == 0;
1302 }
1303 }
1304 print "took $steps steps\n" if DEBUG;
1305 $x->bmul($f); # $x *= 2
1306 }
1307
1308sub _log_10
1309 {
1310 # Internal log function based on reducing input to the range of 0.1 .. 9.99
1311 # and then "correcting" the result to the proper one. Modifies $x in place.
1312 my ($self,$x,$scale) = @_;
1313
1314 # Taking blog() from numbers greater than 10 takes a *very long* time, so we
1315 # break the computation down into parts based on the observation that:
1316 # blog(X*Y) = blog(X) + blog(Y)
1317 # We set Y here to multiples of 10 so that $x becomes below 1 - the smaller
1318 # $x is the faster it gets. Since 2*$x takes about 10 times as
1319 # long, we make it faster by about a factor of 100 by dividing $x by 10.
1320
1321 # The same observation is valid for numbers smaller than 0.1, e.g. computing
1322 # log(1) is fastest, and the further away we get from 1, the longer it takes.
1323 # So we also 'break' this down by multiplying $x with 10 and subtract the
1324 # log(10) afterwards to get the correct result.
1325
1326 # To get $x even closer to 1, we also divide by 2 and then use log(2) to
1327 # correct for this. For instance if $x is 2.4, we use the formula:
1328 # blog(2.4 * 2) == blog (1.2) + blog(2)
1329 # and thus calculate only blog(1.2) and blog(2), which is faster in total
1330 # than calculating blog(2.4).
1331
1332 # In addition, the values for blog(2) and blog(10) are cached.
1333
1334 # Calculate nr of digits before dot:
1335 my $dbd = $MBI->_num($x->{_e});
1336 $dbd = -$dbd if $x->{_es} eq '-';
1337 $dbd += $MBI->_len($x->{_m});
1338
1339 # more than one digit (e.g. at least 10), but *not* exactly 10 to avoid
1340 # infinite recursion
1341
1342 my $calc = 1; # do some calculation?
1343
1344 # disable the shortcut for 10, since we need log(10) and this would recurse
1345 # infinitely deep
1346 if ($x->{_es} eq '+' && $MBI->_is_one($x->{_e}) && $MBI->_is_one($x->{_m}))
1347 {
1348 $dbd = 0; # disable shortcut
1349 # we can use the cached value in these cases
1350 if ($scale <= $LOG_10_A)
1351 {
1352 $x->bzero(); $x->badd($LOG_10); # modify $x in place
1353 $calc = 0; # no need to calc, but round
1354 }
1355 # if we can't use the shortcut, we continue normally
1356 }
1357 else
1358 {
1359 # disable the shortcut for 2, since we maybe have it cached
1360 if (($MBI->_is_zero($x->{_e}) && $MBI->_is_two($x->{_m})))
1361 {
1362 $dbd = 0; # disable shortcut
1363 # we can use the cached value in these cases
1364 if ($scale <= $LOG_2_A)
1365 {
1366 $x->bzero(); $x->badd($LOG_2); # modify $x in place
1367 $calc = 0; # no need to calc, but round
1368 }
1369 # if we can't use the shortcut, we continue normally
1370 }
1371 }
1372
1373 # if $x = 0.1, we know the result must be 0-log(10)
1374 if ($calc != 0 && $x->{_es} eq '-' && $MBI->_is_one($x->{_e}) &&
1375 $MBI->_is_one($x->{_m}))
1376 {
1377 $dbd = 0; # disable shortcut
1378 # we can use the cached value in these cases
1379 if ($scale <= $LOG_10_A)
1380 {
1381 $x->bzero(); $x->bsub($LOG_10);
1382 $calc = 0; # no need to calc, but round
1383 }
1384 }
1385
1386 return if $calc == 0; # already have the result
1387
1388 # default: these correction factors are undef and thus not used
1389 my $l_10; # value of ln(10) to A of $scale
1390 my $l_2; # value of ln(2) to A of $scale
1391
1392 my $two = $self->new(2);
1393
1394 # $x == 2 => 1, $x == 13 => 2, $x == 0.1 => 0, $x == 0.01 => -1
1395 # so don't do this shortcut for 1 or 0
1396 if (($dbd > 1) || ($dbd < 0))
1397 {
1398 # convert our cached value to an object if not already (avoid doing this
1399 # at import() time, since not everybody needs this)
1400 $LOG_10 = $self->new($LOG_10,undef,undef) unless ref $LOG_10;
1401
1402 #print "x = $x, dbd = $dbd, calc = $calc\n";
1403 # got more than one digit before the dot, or more than one zero after the
1404 # dot, so do:
1405 # log(123) == log(1.23) + log(10) * 2
1406 # log(0.0123) == log(1.23) - log(10) * 2
1407
1408 if ($scale <= $LOG_10_A)
1409 {
1410 # use cached value
1411 $l_10 = $LOG_10->copy(); # copy for mul
1412 }
1413 else
1414 {
1415 # else: slower, compute and cache result
1416 # also disable downgrade for this code path
1417 local $Math::BigFloat::downgrade = undef;
1418
1419 # shorten the time to calculate log(10) based on the following:
1420 # log(1.25 * 8) = log(1.25) + log(8)
1421 # = log(1.25) + log(2) + log(2) + log(2)
1422
1423 # first get $l_2 (and possible compute and cache log(2))
1424 $LOG_2 = $self->new($LOG_2,undef,undef) unless ref $LOG_2;
1425 if ($scale <= $LOG_2_A)
1426 {
1427 # use cached value
1428 $l_2 = $LOG_2->copy(); # copy() for the mul below
1429 }
1430 else
1431 {
1432 # else: slower, compute and cache result
1433 $l_2 = $two->copy(); $self->_log($l_2, $scale); # scale+4, actually
1434 $LOG_2 = $l_2->copy(); # cache the result for later
1435 # the copy() is for mul below
1436 $LOG_2_A = $scale;
1437 }
1438
1439 # now calculate log(1.25):
1440 $l_10 = $self->new('1.25'); $self->_log($l_10, $scale); # scale+4, actually
1441
1442 # log(1.25) + log(2) + log(2) + log(2):
1443 $l_10->badd($l_2);
1444 $l_10->badd($l_2);
1445 $l_10->badd($l_2);
1446 $LOG_10 = $l_10->copy(); # cache the result for later
1447 # the copy() is for mul below
1448 $LOG_10_A = $scale;
1449 }
1450 $dbd-- if ($dbd > 1); # 20 => dbd=2, so make it dbd=1
1451 $l_10->bmul( $self->new($dbd)); # log(10) * (digits_before_dot-1)
1452 my $dbd_sign = '+';
1453 if ($dbd < 0)
1454 {
1455 $dbd = -$dbd;
1456 $dbd_sign = '-';
1457 }
1458 ($x->{_e}, $x->{_es}) =
1459 _e_sub( $x->{_e}, $MBI->_new($dbd), $x->{_es}, $dbd_sign); # 123 => 1.23
1460
1461 }
1462
1463 # Now: 0.1 <= $x < 10 (and possible correction in l_10)
1464
1465 ### Since $x in the range 0.5 .. 1.5 is MUCH faster, we do a repeated div
1466 ### or mul by 2 (maximum times 3, since x < 10 and x > 0.1)
1467
1468 $HALF = $self->new($HALF) unless ref($HALF);
1469
1470 my $twos = 0; # default: none (0 times)
1471 while ($x->bacmp($HALF) <= 0) # X <= 0.5
1472 {
1473 $twos--; $x->bmul($two);
1474 }
1475 while ($x->bacmp($two) >= 0) # X >= 2
1476 {
1477 $twos++; $x->bdiv($two,$scale+4); # keep all digits
1478 }
1479 # $twos > 0 => did mul 2, < 0 => did div 2 (but we never did both)
1480 # So calculate correction factor based on ln(2):
1481 if ($twos != 0)
1482 {
1483 $LOG_2 = $self->new($LOG_2,undef,undef) unless ref $LOG_2;
1484 if ($scale <= $LOG_2_A)
1485 {
1486 # use cached value
1487 $l_2 = $LOG_2->copy(); # copy() for the mul below
1488 }
1489 else
1490 {
1491 # else: slower, compute and cache result
1492 # also disable downgrade for this code path
1493 local $Math::BigFloat::downgrade = undef;
1494 $l_2 = $two->copy(); $self->_log($l_2, $scale); # scale+4, actually
1495 $LOG_2 = $l_2->copy(); # cache the result for later
1496 # the copy() is for mul below
1497 $LOG_2_A = $scale;
1498 }
1499 $l_2->bmul($twos); # * -2 => subtract, * 2 => add
1500 }
1501
1502 $self->_log($x,$scale); # need to do the "normal" way
1503 $x->badd($l_10) if defined $l_10; # correct it by ln(10)
1504 $x->badd($l_2) if defined $l_2; # and maybe by ln(2)
1505
1506 # all done, $x contains now the result
1507 $x;
1508 }
1509
1510sub blcm
1511 {
1512 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
1513 # does not modify arguments, but returns new object
1514 # Lowest Common Multiplicator
1515
1516 my ($self,@arg) = objectify(0,@_);
1517 my $x = $self->new(shift @arg);
1518 while (@arg) { $x = Math::BigInt::__lcm($x,shift @arg); }
1519 $x;
1520 }
1521
1522sub bgcd
1523 {
1524 # (BINT or num_str, BINT or num_str) return BINT
1525 # does not modify arguments, but returns new object
1526
1527 my $y = shift;
1528 $y = __PACKAGE__->new($y) if !ref($y);
1529 my $self = ref($y);
1530 my $x = $y->copy()->babs(); # keep arguments
1531
1532 return $x->bnan() if $x->{sign} !~ /^[+-]$/ # x NaN?
1533 || !$x->is_int(); # only for integers now
1534
1535 while (@_)
1536 {
1537 my $t = shift; $t = $self->new($t) if !ref($t);
1538 $y = $t->copy()->babs();
1539
1540 return $x->bnan() if $y->{sign} !~ /^[+-]$/ # y NaN?
1541 || !$y->is_int(); # only for integers now
1542
1543 # greatest common divisor
1544 while (! $y->is_zero())
1545 {
1546 ($x,$y) = ($y->copy(), $x->copy()->bmod($y));
1547 }
1548
1549 last if $x->is_one();
1550 }
1551 $x;
1552 }
1553
1554##############################################################################
1555
1556sub _e_add
1557 {
1558 # Internal helper sub to take two positive integers and their signs and
1559 # then add them. Input ($CALC,$CALC,('+'|'-'),('+'|'-')),
1560 # output ($CALC,('+'|'-'))
1561 my ($x,$y,$xs,$ys) = @_;
1562
1563 # if the signs are equal we can add them (-5 + -3 => -(5 + 3) => -8)
1564 if ($xs eq $ys)
1565 {
1566 $x = $MBI->_add ($x, $y ); # a+b
1567 # the sign follows $xs
1568 return ($x, $xs);
1569 }
1570
1571 my $a = $MBI->_acmp($x,$y);
1572 if ($a > 0)
1573 {
1574 $x = $MBI->_sub ($x , $y); # abs sub
1575 }
1576 elsif ($a == 0)
1577 {
1578 $x = $MBI->_zero(); # result is 0
1579 $xs = '+';
1580 }
1581 else # a < 0
1582 {
1583 $x = $MBI->_sub ( $y, $x, 1 ); # abs sub
1584 $xs = $ys;
1585 }
1586 ($x,$xs);
1587 }
1588
1589sub _e_sub
1590 {
1591 # Internal helper sub to take two positive integers and their signs and
1592 # then subtract them. Input ($CALC,$CALC,('+'|'-'),('+'|'-')),
1593 # output ($CALC,('+'|'-'))
1594 my ($x,$y,$xs,$ys) = @_;
1595
1596 # flip sign
1597 $ys =~ tr/+-/-+/;
1598 _e_add($x,$y,$xs,$ys); # call add (does subtract now)
1599 }
1600
1601###############################################################################
1602# is_foo methods (is_negative, is_positive are inherited from BigInt)
1603
1604sub is_int
1605 {
1606 # return true if arg (BFLOAT or num_str) is an integer
1607 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1608
1609 (($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
1610 ($x->{_es} eq '+')) ? 1 : 0; # 1e-1 => no integer
1611 }
1612
1613sub is_zero
1614 {
1615 # return true if arg (BFLOAT or num_str) is zero
1616 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1617
1618 ($x->{sign} eq '+' && $MBI->_is_zero($x->{_m})) ? 1 : 0;
1619 }
1620
1621sub is_one
1622 {
1623 # return true if arg (BFLOAT or num_str) is +1 or -1 if signis given
1624 my ($self,$x,$sign) = ref($_[0]) ? (undef,@_) : objectify(1,@_);
1625
1626 $sign = '+' if !defined $sign || $sign ne '-';
1627
1628 ($x->{sign} eq $sign &&
1629 $MBI->_is_zero($x->{_e}) &&
1630 $MBI->_is_one($x->{_m}) ) ? 1 : 0;
1631 }
1632
1633sub is_odd
1634 {
1635 # return true if arg (BFLOAT or num_str) is odd or false if even
1636 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1637
1638 (($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
1639 ($MBI->_is_zero($x->{_e})) &&
1640 ($MBI->_is_odd($x->{_m}))) ? 1 : 0;
1641 }
1642
1643sub is_even
1644 {
1645 # return true if arg (BINT or num_str) is even or false if odd
1646 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1647
1648 (($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
1649 ($x->{_es} eq '+') && # 123.45 isn't
1650 ($MBI->_is_even($x->{_m}))) ? 1 : 0; # but 1200 is
1651 }
1652
1653sub bmul
1654 {
1655 # multiply two numbers
1656
1657 # set up parameters
1658 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1659 # objectify is costly, so avoid it
1660 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1661 {
1662 ($self,$x,$y,@r) = objectify(2,@_);
1663 }
1664
1665 return $x if $x->modify('bmul');
1666
1667 return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1668
1669 # inf handling
1670 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
1671 {
1672 return $x->bnan() if $x->is_zero() || $y->is_zero();
1673 # result will always be +-inf:
1674 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
1675 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
1676 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
1677 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
1678 return $x->binf('-');
1679 }
1680
1681 return $upgrade->bmul($x,$y,@r) if defined $upgrade &&
1682 ((!$x->isa($self)) || (!$y->isa($self)));
1683
1684 # aEb * cEd = (a*c)E(b+d)
1685 $MBI->_mul($x->{_m},$y->{_m});
1686 ($x->{_e}, $x->{_es}) = _e_add($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
1687
1688 $r[3] = $y; # no push!
1689
1690 # adjust sign:
1691 $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
1692 $x->bnorm->round(@r);
1693 }
1694
1695sub bmuladd
1696 {
1697 # multiply two numbers and add the third to the result
1698
1699 # set up parameters
1700 my ($self,$x,$y,$z,@r) = objectify(3,@_);
1701
1702 return $x if $x->modify('bmuladd');
1703
1704 return $x->bnan() if (($x->{sign} eq $nan) ||
1705 ($y->{sign} eq $nan) ||
1706 ($z->{sign} eq $nan));
1707
1708 # inf handling
1709 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
1710 {
1711 return $x->bnan() if $x->is_zero() || $y->is_zero();
1712 # result will always be +-inf:
1713 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
1714 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
1715 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
1716 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
1717 return $x->binf('-');
1718 }
1719
1720 return $upgrade->bmul($x,$y,@r) if defined $upgrade &&
1721 ((!$x->isa($self)) || (!$y->isa($self)));
1722
1723 # aEb * cEd = (a*c)E(b+d)
1724 $MBI->_mul($x->{_m},$y->{_m});
1725 ($x->{_e}, $x->{_es}) = _e_add($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
1726
1727 $r[3] = $y; # no push!
1728
1729 # adjust sign:
1730 $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
1731
1732 # z=inf handling (z=NaN handled above)
1733 $x->{sign} = $z->{sign}, return $x if $z->{sign} =~ /^[+-]inf$/;
1734
1735 # take lower of the two e's and adapt m1 to it to match m2
1736 my $e = $z->{_e};
1737 $e = $MBI->_zero() if !defined $e; # if no BFLOAT?
1738 $e = $MBI->_copy($e); # make copy (didn't do it yet)
1739
1740 my $es;
1741
1742 ($e,$es) = _e_sub($e, $x->{_e}, $z->{_es} || '+', $x->{_es});
1743
1744 my $add = $MBI->_copy($z->{_m});
1745
1746 if ($es eq '-') # < 0
1747 {
1748 $MBI->_lsft( $x->{_m}, $e, 10);
1749 ($x->{_e},$x->{_es}) = _e_add($x->{_e}, $e, $x->{_es}, $es);
1750 }
1751 elsif (!$MBI->_is_zero($e)) # > 0
1752 {
1753 $MBI->_lsft($add, $e, 10);
1754 }
1755 # else: both e are the same, so just leave them
1756
1757 if ($x->{sign} eq $z->{sign})
1758 {
1759 # add
1760 $x->{_m} = $MBI->_add($x->{_m}, $add);
1761 }
1762 else
1763 {
1764 ($x->{_m}, $x->{sign}) =
1765 _e_add($x->{_m}, $add, $x->{sign}, $z->{sign});
1766 }
1767
1768 # delete trailing zeros, then round
1769 $x->bnorm()->round(@r);
1770 }
1771
1772sub bdiv
1773 {
1774 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return
1775 # (BFLOAT,BFLOAT) (quo,rem) or BFLOAT (only rem)
1776
1777 # set up parameters
1778 my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_);
1779 # objectify is costly, so avoid it
1780 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1781 {
1782 ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
1783 }
1784
1785 return $x if $x->modify('bdiv');
1786
1787 return $self->_div_inf($x,$y)
1788 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
1789
1790 # x== 0 # also: or y == 1 or y == -1
1791 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
1792
1793 # upgrade ?
1794 return $upgrade->bdiv($upgrade->new($x),$y,$a,$p,$r) if defined $upgrade;
1795
1796 # we need to limit the accuracy to protect against overflow
1797 my $fallback = 0;
1798 my (@params,$scale);
1799 ($x,@params) = $x->_find_round_parameters($a,$p,$r,$y);
1800
1801 return $x if $x->is_nan(); # error in _find_round_parameters?
1802
1803 # no rounding at all, so must use fallback
1804 if (scalar @params == 0)
1805 {
1806 # simulate old behaviour
1807 $params[0] = $self->div_scale(); # and round to it as accuracy
1808 $scale = $params[0]+4; # at least four more for proper round
1809 $params[2] = $r; # round mode by caller or undef
1810 $fallback = 1; # to clear a/p afterwards
1811 }
1812 else
1813 {
1814 # the 4 below is empirical, and there might be cases where it is not
1815 # enough...
1816 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
1817 }
1818
1819 my $rem; $rem = $self->bzero() if wantarray;
1820
1821 $y = $self->new($y) unless $y->isa('Math::BigFloat');
1822
1823 my $lx = $MBI->_len($x->{_m}); my $ly = $MBI->_len($y->{_m});
1824 $scale = $lx if $lx > $scale;
1825 $scale = $ly if $ly > $scale;
1826 my $diff = $ly - $lx;
1827 $scale += $diff if $diff > 0; # if lx << ly, but not if ly << lx!
1828
1829 # already handled inf/NaN/-inf above:
1830
1831 # check that $y is not 1 nor -1 and cache the result:
1832 my $y_not_one = !($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m}));
1833
1834 # flipping the sign of $y will also flip the sign of $x for the special
1835 # case of $x->bsub($x); so we can catch it below:
1836 my $xsign = $x->{sign};
1837 $y->{sign} =~ tr/+-/-+/;
1838
1839 if ($xsign ne $x->{sign})
1840 {
1841 # special case of $x /= $x results in 1
1842 $x->bone(); # "fixes" also sign of $y, since $x is $y
1843 }
1844 else
1845 {
1846 # correct $y's sign again
1847 $y->{sign} =~ tr/+-/-+/;
1848 # continue with normal div code:
1849
1850 # make copy of $x in case of list context for later remainder calculation
1851 if (wantarray && $y_not_one)
1852 {
1853 $rem = $x->copy();
1854 }
1855
1856 $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
1857
1858 # check for / +-1 ( +/- 1E0)
1859 if ($y_not_one)
1860 {
1861 # promote BigInts and it's subclasses (except when already a BigFloat)
1862 $y = $self->new($y) unless $y->isa('Math::BigFloat');
1863
1864 # calculate the result to $scale digits and then round it
1865 # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
1866 $MBI->_lsft($x->{_m},$MBI->_new($scale),10);
1867 $MBI->_div ($x->{_m},$y->{_m}); # a/c
1868
1869 # correct exponent of $x
1870 ($x->{_e},$x->{_es}) = _e_sub($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
1871 # correct for 10**scale
1872 ($x->{_e},$x->{_es}) = _e_sub($x->{_e}, $MBI->_new($scale), $x->{_es}, '+');
1873 $x->bnorm(); # remove trailing 0's
1874 }
1875 } # end else $x != $y
1876
1877 # shortcut to not run through _find_round_parameters again
1878 if (defined $params[0])
1879 {
1880 delete $x->{_a}; # clear before round
1881 $x->bround($params[0],$params[2]); # then round accordingly
1882 }
1883 else
1884 {
1885 delete $x->{_p}; # clear before round
1886 $x->bfround($params[1],$params[2]); # then round accordingly
1887 }
1888 if ($fallback)
1889 {
1890 # clear a/p after round, since user did not request it
1891 delete $x->{_a}; delete $x->{_p};
1892 }
1893
1894 if (wantarray)
1895 {
1896 if ($y_not_one)
1897 {
1898 $rem->bmod($y,@params); # copy already done
1899 }
1900 if ($fallback)
1901 {
1902 # clear a/p after round, since user did not request it
1903 delete $rem->{_a}; delete $rem->{_p};
1904 }
1905 return ($x,$rem);
1906 }
1907 $x;
1908 }
1909
1910sub bmod
1911 {
1912 # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return remainder
1913
1914 # set up parameters
1915 my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_);
1916 # objectify is costly, so avoid it
1917 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1918 {
1919 ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
1920 }
1921
1922 return $x if $x->modify('bmod');
1923
1924 # handle NaN, inf, -inf
1925 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1926 {
1927 my ($d,$re) = $self->SUPER::_div_inf($x,$y);
1928 $x->{sign} = $re->{sign};
1929 $x->{_e} = $re->{_e};
1930 $x->{_m} = $re->{_m};
1931 return $x->round($a,$p,$r,$y);
1932 }
1933 if ($y->is_zero())
1934 {
1935 return $x->bnan() if $x->is_zero();
1936 return $x;
1937 }
1938
1939 return $x->bzero() if $x->is_zero()
1940 || ($x->is_int() &&
1941 # check that $y == +1 or $y == -1:
1942 ($MBI->_is_zero($y->{_e}) && $MBI->_is_one($y->{_m})));
1943
1944 my $cmp = $x->bacmp($y); # equal or $x < $y?
1945 return $x->bzero($a,$p) if $cmp == 0; # $x == $y => result 0
1946
1947 # only $y of the operands negative?
1948 my $neg = 0; $neg = 1 if $x->{sign} ne $y->{sign};
1949
1950 $x->{sign} = $y->{sign}; # calc sign first
1951 return $x->round($a,$p,$r) if $cmp < 0 && $neg == 0; # $x < $y => result $x
1952
1953 my $ym = $MBI->_copy($y->{_m});
1954
1955 # 2e1 => 20
1956 $MBI->_lsft( $ym, $y->{_e}, 10)
1957 if $y->{_es} eq '+' && !$MBI->_is_zero($y->{_e});
1958
1959 # if $y has digits after dot
1960 my $shifty = 0; # correct _e of $x by this
1961 if ($y->{_es} eq '-') # has digits after dot
1962 {
1963 # 123 % 2.5 => 1230 % 25 => 5 => 0.5
1964 $shifty = $MBI->_num($y->{_e}); # no more digits after dot
1965 $MBI->_lsft($x->{_m}, $y->{_e}, 10);# 123 => 1230, $y->{_m} is already 25
1966 }
1967 # $ym is now mantissa of $y based on exponent 0
1968
1969 my $shiftx = 0; # correct _e of $x by this
1970 if ($x->{_es} eq '-') # has digits after dot
1971 {
1972 # 123.4 % 20 => 1234 % 200
1973 $shiftx = $MBI->_num($x->{_e}); # no more digits after dot
1974 $MBI->_lsft($ym, $x->{_e}, 10); # 123 => 1230
1975 }
1976 # 123e1 % 20 => 1230 % 20
1977 if ($x->{_es} eq '+' && !$MBI->_is_zero($x->{_e}))
1978 {
1979 $MBI->_lsft( $x->{_m}, $x->{_e},10); # es => '+' here
1980 }
1981
1982 $x->{_e} = $MBI->_new($shiftx);
1983 $x->{_es} = '+';
1984 $x->{_es} = '-' if $shiftx != 0 || $shifty != 0;
1985 $MBI->_add( $x->{_e}, $MBI->_new($shifty)) if $shifty != 0;
1986
1987 # now mantissas are equalized, exponent of $x is adjusted, so calc result
1988
1989 $x->{_m} = $MBI->_mod( $x->{_m}, $ym);
1990
1991 $x->{sign} = '+' if $MBI->_is_zero($x->{_m}); # fix sign for -0
1992 $x->bnorm();
1993
1994 if ($neg != 0) # one of them negative => correct in place
1995 {
1996 my $r = $y - $x;
1997 $x->{_m} = $r->{_m};
1998 $x->{_e} = $r->{_e};
1999 $x->{_es} = $r->{_es};
2000 $x->{sign} = '+' if $MBI->_is_zero($x->{_m}); # fix sign for -0
2001 $x->bnorm();
2002 }
2003
2004 $x->round($a,$p,$r,$y); # round and return
2005 }
2006
2007sub broot
2008 {
2009 # calculate $y'th root of $x
2010
2011 # set up parameters
2012 my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_);
2013 # objectify is costly, so avoid it
2014 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
2015 {
2016 ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
2017 }
2018
2019 return $x if $x->modify('broot');
2020
2021 # NaN handling: $x ** 1/0, x or y NaN, or y inf/-inf or y == 0
2022 return $x->bnan() if $x->{sign} !~ /^\+/ || $y->is_zero() ||
2023 $y->{sign} !~ /^\+$/;
2024
2025 return $x if $x->is_zero() || $x->is_one() || $x->is_inf() || $y->is_one();
2026
2027 # we need to limit the accuracy to protect against overflow
2028 my $fallback = 0;
2029 my (@params,$scale);
2030 ($x,@params) = $x->_find_round_parameters($a,$p,$r);
2031
2032 return $x if $x->is_nan(); # error in _find_round_parameters?
2033
2034 # no rounding at all, so must use fallback
2035 if (scalar @params == 0)
2036 {
2037 # simulate old behaviour
2038 $params[0] = $self->div_scale(); # and round to it as accuracy
2039 $scale = $params[0]+4; # at least four more for proper round
2040 $params[2] = $r; # round mode by caller or undef
2041 $fallback = 1; # to clear a/p afterwards
2042 }
2043 else
2044 {
2045 # the 4 below is empirical, and there might be cases where it is not
2046 # enough...
2047 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2048 }
2049
2050 # when user set globals, they would interfere with our calculation, so
2051 # disable them and later re-enable them
2052 no strict 'refs';
2053 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
2054 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
2055 # we also need to disable any set A or P on $x (_find_round_parameters took
2056 # them already into account), since these would interfere, too
2057 delete $x->{_a}; delete $x->{_p};
2058 # need to disable $upgrade in BigInt, to avoid deep recursion
2059 local $Math::BigInt::upgrade = undef; # should be really parent class vs MBI
2060
2061 # remember sign and make $x positive, since -4 ** (1/2) => -2
2062 my $sign = 0; $sign = 1 if $x->{sign} eq '-'; $x->{sign} = '+';
2063
2064 my $is_two = 0;
2065 if ($y->isa('Math::BigFloat'))
2066 {
2067 $is_two = ($y->{sign} eq '+' && $MBI->_is_two($y->{_m}) && $MBI->_is_zero($y->{_e}));
2068 }
2069 else
2070 {
2071 $is_two = ($y == 2);
2072 }
2073
2074 # normal square root if $y == 2:
2075 if ($is_two)
2076 {
2077 $x->bsqrt($scale+4);
2078 }
2079 elsif ($y->is_one('-'))
2080 {
2081 # $x ** -1 => 1/$x
2082 my $u = $self->bone()->bdiv($x,$scale);
2083 # copy private parts over
2084 $x->{_m} = $u->{_m};
2085 $x->{_e} = $u->{_e};
2086 $x->{_es} = $u->{_es};
2087 }
2088 else
2089 {
2090 # calculate the broot() as integer result first, and if it fits, return
2091 # it rightaway (but only if $x and $y are integer):
2092
2093 my $done = 0; # not yet
2094 if ($y->is_int() && $x->is_int())
2095 {
2096 my $i = $MBI->_copy( $x->{_m} );
2097 $MBI->_lsft( $i, $x->{_e}, 10 ) unless $MBI->_is_zero($x->{_e});
2098 my $int = Math::BigInt->bzero();
2099 $int->{value} = $i;
2100 $int->broot($y->as_number());
2101 # if ($exact)
2102 if ($int->copy()->bpow($y) == $x)
2103 {
2104 # found result, return it
2105 $x->{_m} = $int->{value};
2106 $x->{_e} = $MBI->_zero();
2107 $x->{_es} = '+';
2108 $x->bnorm();
2109 $done = 1;
2110 }
2111 }
2112 if ($done == 0)
2113 {
2114 my $u = $self->bone()->bdiv($y,$scale+4);
2115 delete $u->{_a}; delete $u->{_p}; # otherwise it conflicts
2116 $x->bpow($u,$scale+4); # el cheapo
2117 }
2118 }
2119 $x->bneg() if $sign == 1;
2120
2121 # shortcut to not run through _find_round_parameters again
2122 if (defined $params[0])
2123 {
2124 $x->bround($params[0],$params[2]); # then round accordingly
2125 }
2126 else
2127 {
2128 $x->bfround($params[1],$params[2]); # then round accordingly
2129 }
2130 if ($fallback)
2131 {
2132 # clear a/p after round, since user did not request it
2133 delete $x->{_a}; delete $x->{_p};
2134 }
2135 # restore globals
2136 $$abr = $ab; $$pbr = $pb;
2137 $x;
2138 }
2139
2140sub bsqrt
2141 {
2142 # calculate square root
2143 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
2144
2145 return $x if $x->modify('bsqrt');
2146
2147 return $x->bnan() if $x->{sign} !~ /^[+]/; # NaN, -inf or < 0
2148 return $x if $x->{sign} eq '+inf'; # sqrt(inf) == inf
2149 return $x->round($a,$p,$r) if $x->is_zero() || $x->is_one();
2150
2151 # we need to limit the accuracy to protect against overflow
2152 my $fallback = 0;
2153 my (@params,$scale);
2154 ($x,@params) = $x->_find_round_parameters($a,$p,$r);
2155
2156 return $x if $x->is_nan(); # error in _find_round_parameters?
2157
2158 # no rounding at all, so must use fallback
2159 if (scalar @params == 0)
2160 {
2161 # simulate old behaviour
2162 $params[0] = $self->div_scale(); # and round to it as accuracy
2163 $scale = $params[0]+4; # at least four more for proper round
2164 $params[2] = $r; # round mode by caller or undef
2165 $fallback = 1; # to clear a/p afterwards
2166 }
2167 else
2168 {
2169 # the 4 below is empirical, and there might be cases where it is not
2170 # enough...
2171 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2172 }
2173
2174 # when user set globals, they would interfere with our calculation, so
2175 # disable them and later re-enable them
2176 no strict 'refs';
2177 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
2178 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
2179 # we also need to disable any set A or P on $x (_find_round_parameters took
2180 # them already into account), since these would interfere, too
2181 delete $x->{_a}; delete $x->{_p};
2182 # need to disable $upgrade in BigInt, to avoid deep recursion
2183 local $Math::BigInt::upgrade = undef; # should be really parent class vs MBI
2184
2185 my $i = $MBI->_copy( $x->{_m} );
2186 $MBI->_lsft( $i, $x->{_e}, 10 ) unless $MBI->_is_zero($x->{_e});
2187 my $xas = Math::BigInt->bzero();
2188 $xas->{value} = $i;
2189
2190 my $gs = $xas->copy()->bsqrt(); # some guess
2191
2192 if (($x->{_es} ne '-') # guess can't be accurate if there are
2193 # digits after the dot
2194 && ($xas->bacmp($gs * $gs) == 0)) # guess hit the nail on the head?
2195 {
2196 # exact result, copy result over to keep $x
2197 $x->{_m} = $gs->{value}; $x->{_e} = $MBI->_zero(); $x->{_es} = '+';
2198 $x->bnorm();
2199 # shortcut to not run through _find_round_parameters again
2200 if (defined $params[0])
2201 {
2202 $x->bround($params[0],$params[2]); # then round accordingly
2203 }
2204 else
2205 {
2206 $x->bfround($params[1],$params[2]); # then round accordingly
2207 }
2208 if ($fallback)
2209 {
2210 # clear a/p after round, since user did not request it
2211 delete $x->{_a}; delete $x->{_p};
2212 }
2213 # re-enable A and P, upgrade is taken care of by "local"
2214 ${"$self\::accuracy"} = $ab; ${"$self\::precision"} = $pb;
2215 return $x;
2216 }
2217
2218 # sqrt(2) = 1.4 because sqrt(2*100) = 1.4*10; so we can increase the accuracy
2219 # of the result by multiplying the input by 100 and then divide the integer
2220 # result of sqrt(input) by 10. Rounding afterwards returns the real result.
2221
2222 # The following steps will transform 123.456 (in $x) into 123456 (in $y1)
2223 my $y1 = $MBI->_copy($x->{_m});
2224
2225 my $length = $MBI->_len($y1);
2226
2227 # Now calculate how many digits the result of sqrt(y1) would have
2228 my $digits = int($length / 2);
2229
2230 # But we need at least $scale digits, so calculate how many are missing
2231 my $shift = $scale - $digits;
2232
2233 # This happens if the input had enough digits
2234 # (we take care of integer guesses above)
2235 $shift = 0 if $shift < 0;
2236
2237 # Multiply in steps of 100, by shifting left two times the "missing" digits
2238 my $s2 = $shift * 2;
2239
2240 # We now make sure that $y1 has the same odd or even number of digits than
2241 # $x had. So when _e of $x is odd, we must shift $y1 by one digit left,
2242 # because we always must multiply by steps of 100 (sqrt(100) is 10) and not
2243 # steps of 10. The length of $x does not count, since an even or odd number
2244 # of digits before the dot is not changed by adding an even number of digits
2245 # after the dot (the result is still odd or even digits long).
2246 $s2++ if $MBI->_is_odd($x->{_e});
2247
2248 $MBI->_lsft( $y1, $MBI->_new($s2), 10);
2249
2250 # now take the square root and truncate to integer
2251 $y1 = $MBI->_sqrt($y1);
2252
2253 # By "shifting" $y1 right (by creating a negative _e) we calculate the final
2254 # result, which is than later rounded to the desired scale.
2255
2256 # calculate how many zeros $x had after the '.' (or before it, depending
2257 # on sign of $dat, the result should have half as many:
2258 my $dat = $MBI->_num($x->{_e});
2259 $dat = -$dat if $x->{_es} eq '-';
2260 $dat += $length;
2261
2262 if ($dat > 0)
2263 {
2264 # no zeros after the dot (e.g. 1.23, 0.49 etc)
2265 # preserve half as many digits before the dot than the input had
2266 # (but round this "up")
2267 $dat = int(($dat+1)/2);
2268 }
2269 else
2270 {
2271 $dat = int(($dat)/2);
2272 }
2273 $dat -= $MBI->_len($y1);
2274 if ($dat < 0)
2275 {
2276 $dat = abs($dat);
2277 $x->{_e} = $MBI->_new( $dat );
2278 $x->{_es} = '-';
2279 }
2280 else
2281 {
2282 $x->{_e} = $MBI->_new( $dat );
2283 $x->{_es} = '+';
2284 }
2285 $x->{_m} = $y1;
2286 $x->bnorm();
2287
2288 # shortcut to not run through _find_round_parameters again
2289 if (defined $params[0])
2290 {
2291 $x->bround($params[0],$params[2]); # then round accordingly
2292 }
2293 else
2294 {
2295 $x->bfround($params[1],$params[2]); # then round accordingly
2296 }
2297 if ($fallback)
2298 {
2299 # clear a/p after round, since user did not request it
2300 delete $x->{_a}; delete $x->{_p};
2301 }
2302 # restore globals
2303 $$abr = $ab; $$pbr = $pb;
2304 $x;
2305 }
2306
2307sub bfac
2308 {
2309 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
2310 # compute factorial number, modifies first argument
2311
2312 # set up parameters
2313 my ($self,$x,@r) = (ref($_[0]),@_);
2314 # objectify is costly, so avoid it
2315 ($self,$x,@r) = objectify(1,@_) if !ref($x);
2316
2317 # inf => inf
2318 return $x if $x->modify('bfac') || $x->{sign} eq '+inf';
2319
2320 return $x->bnan()
2321 if (($x->{sign} ne '+') || # inf, NaN, <0 etc => NaN
2322 ($x->{_es} ne '+')); # digits after dot?
2323
2324 # use BigInt's bfac() for faster calc
2325 if (! $MBI->_is_zero($x->{_e}))
2326 {
2327 $MBI->_lsft($x->{_m}, $x->{_e},10); # change 12e1 to 120e0
2328 $x->{_e} = $MBI->_zero(); # normalize
2329 $x->{_es} = '+';
2330 }
2331 $MBI->_fac($x->{_m}); # calculate factorial
2332 $x->bnorm()->round(@r); # norm again and round result
2333 }
2334
2335sub _pow
2336 {
2337 # Calculate a power where $y is a non-integer, like 2 ** 0.3
2338 my ($x,$y,@r) = @_;
2339 my $self = ref($x);
2340
2341 # if $y == 0.5, it is sqrt($x)
2342 $HALF = $self->new($HALF) unless ref($HALF);
2343 return $x->bsqrt(@r,$y) if $y->bcmp($HALF) == 0;
2344
2345 # Using:
2346 # a ** x == e ** (x * ln a)
2347
2348 # u = y * ln x
2349 # _ _
2350 # Taylor: | u u^2 u^3 |
2351 # x ** y = 1 + | --- + --- + ----- + ... |
2352 # |_ 1 1*2 1*2*3 _|
2353
2354 # we need to limit the accuracy to protect against overflow
2355 my $fallback = 0;
2356 my ($scale,@params);
2357 ($x,@params) = $x->_find_round_parameters(@r);
2358
2359 return $x if $x->is_nan(); # error in _find_round_parameters?
2360
2361 # no rounding at all, so must use fallback
2362 if (scalar @params == 0)
2363 {
2364 # simulate old behaviour
2365 $params[0] = $self->div_scale(); # and round to it as accuracy
2366 $params[1] = undef; # disable P
2367 $scale = $params[0]+4; # at least four more for proper round
2368 $params[2] = $r[2]; # round mode by caller or undef
2369 $fallback = 1; # to clear a/p afterwards
2370 }
2371 else
2372 {
2373 # the 4 below is empirical, and there might be cases where it is not
2374 # enough...
2375 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2376 }
2377
2378 # when user set globals, they would interfere with our calculation, so
2379 # disable them and later re-enable them
2380 no strict 'refs';
2381 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
2382 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
2383 # we also need to disable any set A or P on $x (_find_round_parameters took
2384 # them already into account), since these would interfere, too
2385 delete $x->{_a}; delete $x->{_p};
2386 # need to disable $upgrade in BigInt, to avoid deep recursion
2387 local $Math::BigInt::upgrade = undef;
2388
2389 my ($limit,$v,$u,$below,$factor,$next,$over);
2390
2391 $u = $x->copy()->blog(undef,$scale)->bmul($y);
2392 $v = $self->bone(); # 1
2393 $factor = $self->new(2); # 2
2394 $x->bone(); # first term: 1
2395
2396 $below = $v->copy();
2397 $over = $u->copy();
2398
2399 $limit = $self->new("1E-". ($scale-1));
2400 #my $steps = 0;
2401 while (3 < 5)
2402 {
2403 # we calculate the next term, and add it to the last
2404 # when the next term is below our limit, it won't affect the outcome
2405 # anymore, so we stop:
2406 $next = $over->copy()->bdiv($below,$scale);
2407 last if $next->bacmp($limit) <= 0;
2408 $x->badd($next);
2409 # calculate things for the next term
2410 $over *= $u; $below *= $factor; $factor->binc();
2411
2412 last if $x->{sign} !~ /^[-+]$/;
2413
2414 #$steps++;
2415 }
2416
2417 # shortcut to not run through _find_round_parameters again
2418 if (defined $params[0])
2419 {
2420 $x->bround($params[0],$params[2]); # then round accordingly
2421 }
2422 else
2423 {
2424 $x->bfround($params[1],$params[2]); # then round accordingly
2425 }
2426 if ($fallback)
2427 {
2428 # clear a/p after round, since user did not request it
2429 delete $x->{_a}; delete $x->{_p};
2430 }
2431 # restore globals
2432 $$abr = $ab; $$pbr = $pb;
2433 $x;
2434 }
2435
2436sub bpow
2437 {
2438 # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
2439 # compute power of two numbers, second arg is used as integer
2440 # modifies first argument
2441
2442 # set up parameters
2443 my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_);
2444 # objectify is costly, so avoid it
2445 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
2446 {
2447 ($self,$x,$y,$a,$p,$r) = objectify(2,@_);
2448 }
2449
2450 return $x if $x->modify('bpow');
2451
2452 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
2453 return $x if $x->{sign} =~ /^[+-]inf$/;
2454
2455 # cache the result of is_zero
2456 my $y_is_zero = $y->is_zero();
2457 return $x->bone() if $y_is_zero;
2458 return $x if $x->is_one() || $y->is_one();
2459
2460 my $x_is_zero = $x->is_zero();
2461 return $x->_pow($y,$a,$p,$r) if !$x_is_zero && !$y->is_int(); # non-integer power
2462
2463 my $y1 = $y->as_number()->{value}; # make MBI part
2464
2465 # if ($x == -1)
2466 if ($x->{sign} eq '-' && $MBI->_is_one($x->{_m}) && $MBI->_is_zero($x->{_e}))
2467 {
2468 # if $x == -1 and odd/even y => +1/-1 because +-1 ^ (+-1) => +-1
2469 return $MBI->_is_odd($y1) ? $x : $x->babs(1);
2470 }
2471 if ($x_is_zero)
2472 {
2473 return $x if $y->{sign} eq '+'; # 0**y => 0 (if not y <= 0)
2474 # 0 ** -y => 1 / (0 ** y) => 1 / 0! (1 / 0 => +inf)
2475 return $x->binf();
2476 }
2477
2478 my $new_sign = '+';
2479 $new_sign = $MBI->_is_odd($y1) ? '-' : '+' if $x->{sign} ne '+';
2480
2481 # calculate $x->{_m} ** $y and $x->{_e} * $y separately (faster)
2482 $x->{_m} = $MBI->_pow( $x->{_m}, $y1);
2483 $x->{_e} = $MBI->_mul ($x->{_e}, $y1);
2484
2485 $x->{sign} = $new_sign;
2486 $x->bnorm();
2487 if ($y->{sign} eq '-')
2488 {
2489 # modify $x in place!
2490 my $z = $x->copy(); $x->bone();
2491 return scalar $x->bdiv($z,$a,$p,$r); # round in one go (might ignore y's A!)
2492 }
2493 $x->round($a,$p,$r,$y);
2494 }
2495
2496sub bmodpow
2497 {
2498 # takes a very large number to a very large exponent in a given very
2499 # large modulus, quickly, thanks to binary exponentiation. Supports
2500 # negative exponents.
2501 my ($self,$num,$exp,$mod,@r) = objectify(3,@_);
2502
2503 return $num if $num->modify('bmodpow');
2504
2505 # check modulus for valid values
2506 return $num->bnan() if ($mod->{sign} ne '+' # NaN, - , -inf, +inf
2507 || $mod->is_zero());
2508
2509 # check exponent for valid values
2510 if ($exp->{sign} =~ /\w/)
2511 {
2512 # i.e., if it's NaN, +inf, or -inf...
2513 return $num->bnan();
2514 }
2515
2516 $num->bmodinv ($mod) if ($exp->{sign} eq '-');
2517
2518 # check num for valid values (also NaN if there was no inverse but $exp < 0)
2519 return $num->bnan() if $num->{sign} !~ /^[+-]$/;
2520
2521 # $mod is positive, sign on $exp is ignored, result also positive
2522
2523 # XXX TODO: speed it up when all three numbers are integers
2524 $num->bpow($exp)->bmod($mod);
2525 }
2526
2527###############################################################################
2528# trigonometric functions
2529
2530# helper function for bpi() and batan2(), calculates arcus tanges (1/x)
2531
2532sub _atan_inv
2533 {
2534 # return a/b so that a/b approximates atan(1/x) to at least limit digits
2535 my ($self, $x, $limit) = @_;
2536
2537 # Taylor: x^3 x^5 x^7 x^9
2538 # atan = x - --- + --- - --- + --- - ...
2539 # 3 5 7 9
2540
2541 # 1 1 1 1
2542 # atan 1/x = - - ------- + ------- - ------- + ...
2543 # x x^3 * 3 x^5 * 5 x^7 * 7
2544
2545 # 1 1 1 1
2546 # atan 1/x = - - --------- + ---------- - ----------- + ...
2547 # 5 3 * 125 5 * 3125 7 * 78125
2548
2549 # Subtraction/addition of a rational:
2550
2551 # 5 7 5*3 +- 7*4
2552 # - +- - = ----------
2553 # 4 3 4*3
2554
2555 # Term: N N+1
2556 #
2557 # a 1 a * d * c +- b
2558 # ----- +- ------------------ = ----------------
2559 # b d * c b * d * c
2560
2561 # since b1 = b0 * (d-2) * c
2562
2563 # a 1 a * d +- b / c
2564 # ----- +- ------------------ = ----------------
2565 # b d * c b * d
2566
2567 # and d = d + 2
2568 # and c = c * x * x
2569
2570 # u = d * c
2571 # stop if length($u) > limit
2572 # a = a * u +- b
2573 # b = b * u
2574 # d = d + 2
2575 # c = c * x * x
2576 # sign = 1 - sign
2577
2578 my $a = $MBI->_one();
2579 my $b = $MBI->_copy($x);
2580
2581 my $x2 = $MBI->_mul( $MBI->_copy($x), $b); # x2 = x * x
2582 my $d = $MBI->_new( 3 ); # d = 3
2583 my $c = $MBI->_mul( $MBI->_copy($x), $x2); # c = x ^ 3
2584 my $two = $MBI->_new( 2 );
2585
2586 # run the first step unconditionally
2587 my $u = $MBI->_mul( $MBI->_copy($d), $c);
2588 $a = $MBI->_mul($a, $u);
2589 $a = $MBI->_sub($a, $b);
2590 $b = $MBI->_mul($b, $u);
2591 $d = $MBI->_add($d, $two);
2592 $c = $MBI->_mul($c, $x2);
2593
2594 # a is now a * (d-3) * c
2595 # b is now b * (d-2) * c
2596
2597 # run the second step unconditionally
2598 $u = $MBI->_mul( $MBI->_copy($d), $c);
2599 $a = $MBI->_mul($a, $u);
2600 $a = $MBI->_add($a, $b);
2601 $b = $MBI->_mul($b, $u);
2602 $d = $MBI->_add($d, $two);
2603 $c = $MBI->_mul($c, $x2);
2604
2605 # a is now a * (d-3) * (d-5) * c * c
2606 # b is now b * (d-2) * (d-4) * c * c
2607
2608 # so we can remove c * c from both a and b to shorten the numbers involved:
2609 $a = $MBI->_div($a, $x2);
2610 $b = $MBI->_div($b, $x2);
2611 $a = $MBI->_div($a, $x2);
2612 $b = $MBI->_div($b, $x2);
2613
2614# my $step = 0;
2615 my $sign = 0; # 0 => -, 1 => +
2616 while (3 < 5)
2617 {
2618# $step++;
2619# if (($i++ % 100) == 0)
2620# {
2621# print "a=",$MBI->_str($a),"\n";
2622# print "b=",$MBI->_str($b),"\n";
2623# }
2624# print "d=",$MBI->_str($d),"\n";
2625# print "x2=",$MBI->_str($x2),"\n";
2626# print "c=",$MBI->_str($c),"\n";
2627
2628 my $u = $MBI->_mul( $MBI->_copy($d), $c);
2629 # use _alen() for libs like GMP where _len() would be O(N^2)
2630 last if $MBI->_alen($u) > $limit;
2631 my ($bc,$r) = $MBI->_div( $MBI->_copy($b), $c);
2632 if ($MBI->_is_zero($r))
2633 {
2634 # b / c is an integer, so we can remove c from all terms
2635 # this happens almost every time:
2636 $a = $MBI->_mul($a, $d);
2637 $a = $MBI->_sub($a, $bc) if $sign == 0;
2638 $a = $MBI->_add($a, $bc) if $sign == 1;
2639 $b = $MBI->_mul($b, $d);
2640 }
2641 else
2642 {
2643 # b / c is not an integer, so we keep c in the terms
2644 # this happens very rarely, for instance for x = 5, this happens only
2645 # at the following steps:
2646 # 1, 5, 14, 32, 72, 157, 340, ...
2647 $a = $MBI->_mul($a, $u);
2648 $a = $MBI->_sub($a, $b) if $sign == 0;
2649 $a = $MBI->_add($a, $b) if $sign == 1;
2650 $b = $MBI->_mul($b, $u);
2651 }
2652 $d = $MBI->_add($d, $two);
2653 $c = $MBI->_mul($c, $x2);
2654 $sign = 1 - $sign;
2655
2656 }
2657
2658# print "Took $step steps for ", $MBI->_str($x),"\n";
2659# print "a=",$MBI->_str($a),"\n"; print "b=",$MBI->_str($b),"\n";
2660 # return a/b so that a/b approximates atan(1/x)
2661 ($a,$b);
2662 }
2663
2664sub bpi
2665 {
2666 my ($self,$n) = @_;
2667 if (@_ == 0)
2668 {
2669 $self = $class;
2670 }
2671 if (@_ == 1)
2672 {
2673 # called like Math::BigFloat::bpi(10);
2674 $n = $self; $self = $class;
2675 # called like Math::BigFloat->bpi();
2676 $n = undef if $n eq 'Math::BigFloat';
2677 }
2678 $self = ref($self) if ref($self);
2679 my $fallback = defined $n ? 0 : 1;
2680 $n = 40 if !defined $n || $n < 1;
2681
2682 # after 黃見利 (Hwang Chien-Lih) (1997)
2683 # pi/4 = 183 * atan(1/239) + 32 * atan(1/1023) – 68 * atan(1/5832)
2684 # + 12 * atan(1/110443) - 12 * atan(1/4841182) - 100 * atan(1/6826318)
2685
2686 # a few more to prevent rounding errors
2687 $n += 4;
2688
2689 my ($a,$b) = $self->_atan_inv( $MBI->_new(239),$n);
2690 my ($c,$d) = $self->_atan_inv( $MBI->_new(1023),$n);
2691 my ($e,$f) = $self->_atan_inv( $MBI->_new(5832),$n);
2692 my ($g,$h) = $self->_atan_inv( $MBI->_new(110443),$n);
2693 my ($i,$j) = $self->_atan_inv( $MBI->_new(4841182),$n);
2694 my ($k,$l) = $self->_atan_inv( $MBI->_new(6826318),$n);
2695
2696 $MBI->_mul($a, $MBI->_new(732));
2697 $MBI->_mul($c, $MBI->_new(128));
2698 $MBI->_mul($e, $MBI->_new(272));
2699 $MBI->_mul($g, $MBI->_new(48));
2700 $MBI->_mul($i, $MBI->_new(48));
2701 $MBI->_mul($k, $MBI->_new(400));
2702
2703 my $x = $self->bone(); $x->{_m} = $a; my $x_d = $self->bone(); $x_d->{_m} = $b;
2704 my $y = $self->bone(); $y->{_m} = $c; my $y_d = $self->bone(); $y_d->{_m} = $d;
2705 my $z = $self->bone(); $z->{_m} = $e; my $z_d = $self->bone(); $z_d->{_m} = $f;
2706 my $u = $self->bone(); $u->{_m} = $g; my $u_d = $self->bone(); $u_d->{_m} = $h;
2707 my $v = $self->bone(); $v->{_m} = $i; my $v_d = $self->bone(); $v_d->{_m} = $j;
2708 my $w = $self->bone(); $w->{_m} = $k; my $w_d = $self->bone(); $w_d->{_m} = $l;
2709 $x->bdiv($x_d, $n);
2710 $y->bdiv($y_d, $n);
2711 $z->bdiv($z_d, $n);
2712 $u->bdiv($u_d, $n);
2713 $v->bdiv($v_d, $n);
2714 $w->bdiv($w_d, $n);
2715
2716 delete $x->{_a}; delete $y->{_a}; delete $z->{_a};
2717 delete $u->{_a}; delete $v->{_a}; delete $w->{_a};
2718 $x->badd($y)->bsub($z)->badd($u)->bsub($v)->bsub($w);
2719
2720 $x->bround($n-4);
2721 delete $x->{_a} if $fallback == 1;
2722 $x;
2723 }
2724
2725sub bcos
2726 {
2727 # Calculate a cosinus of x.
2728 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
2729
2730 # Taylor: x^2 x^4 x^6 x^8
2731 # cos = 1 - --- + --- - --- + --- ...
2732 # 2! 4! 6! 8!
2733
2734 # we need to limit the accuracy to protect against overflow
2735 my $fallback = 0;
2736 my ($scale,@params);
2737 ($x,@params) = $x->_find_round_parameters(@r);
2738
2739 # constant object or error in _find_round_parameters?
2740 return $x if $x->modify('bcos') || $x->is_nan();
2741
2742 return $x->bone(@r) if $x->is_zero();
2743
2744 # no rounding at all, so must use fallback
2745 if (scalar @params == 0)
2746 {
2747 # simulate old behaviour
2748 $params[0] = $self->div_scale(); # and round to it as accuracy
2749 $params[1] = undef; # disable P
2750 $scale = $params[0]+4; # at least four more for proper round
2751 $params[2] = $r[2]; # round mode by caller or undef
2752 $fallback = 1; # to clear a/p afterwards
2753 }
2754 else
2755 {
2756 # the 4 below is empirical, and there might be cases where it is not
2757 # enough...
2758 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2759 }
2760
2761 # when user set globals, they would interfere with our calculation, so
2762 # disable them and later re-enable them
2763 no strict 'refs';
2764 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
2765 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
2766 # we also need to disable any set A or P on $x (_find_round_parameters took
2767 # them already into account), since these would interfere, too
2768 delete $x->{_a}; delete $x->{_p};
2769 # need to disable $upgrade in BigInt, to avoid deep recursion
2770 local $Math::BigInt::upgrade = undef;
2771
2772 my $last = 0;
2773 my $over = $x * $x; # X ^ 2
2774 my $x2 = $over->copy(); # X ^ 2; difference between terms
2775 my $sign = 1; # start with -=
2776 my $below = $self->new(2); my $factorial = $self->new(3);
2777 $x->bone(); delete $x->{_a}; delete $x->{_p};
2778
2779 my $limit = $self->new("1E-". ($scale-1));
2780 #my $steps = 0;
2781 while (3 < 5)
2782 {
2783 # we calculate the next term, and add it to the last
2784 # when the next term is below our limit, it won't affect the outcome
2785 # anymore, so we stop:
2786 my $next = $over->copy()->bdiv($below,$scale);
2787 last if $next->bacmp($limit) <= 0;
2788
2789 if ($sign == 0)
2790 {
2791 $x->badd($next);
2792 }
2793 else
2794 {
2795 $x->bsub($next);
2796 }
2797 $sign = 1-$sign; # alternate
2798 # calculate things for the next term
2799 $over->bmul($x2); # $x*$x
2800 $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2801 $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2802 }
2803
2804 # shortcut to not run through _find_round_parameters again
2805 if (defined $params[0])
2806 {
2807 $x->bround($params[0],$params[2]); # then round accordingly
2808 }
2809 else
2810 {
2811 $x->bfround($params[1],$params[2]); # then round accordingly
2812 }
2813 if ($fallback)
2814 {
2815 # clear a/p after round, since user did not request it
2816 delete $x->{_a}; delete $x->{_p};
2817 }
2818 # restore globals
2819 $$abr = $ab; $$pbr = $pb;
2820 $x;
2821 }
2822
2823sub bsin
2824 {
2825 # Calculate a sinus of x.
2826 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
2827
2828 # taylor: x^3 x^5 x^7 x^9
2829 # sin = x - --- + --- - --- + --- ...
2830 # 3! 5! 7! 9!
2831
2832 # we need to limit the accuracy to protect against overflow
2833 my $fallback = 0;
2834 my ($scale,@params);
2835 ($x,@params) = $x->_find_round_parameters(@r);
2836
2837 # constant object or error in _find_round_parameters?
2838 return $x if $x->modify('bsin') || $x->is_nan();
2839
2840 return $x->bzero(@r) if $x->is_zero();
2841
2842 # no rounding at all, so must use fallback
2843 if (scalar @params == 0)
2844 {
2845 # simulate old behaviour
2846 $params[0] = $self->div_scale(); # and round to it as accuracy
2847 $params[1] = undef; # disable P
2848 $scale = $params[0]+4; # at least four more for proper round
2849 $params[2] = $r[2]; # round mode by caller or undef
2850 $fallback = 1; # to clear a/p afterwards
2851 }
2852 else
2853 {
2854 # the 4 below is empirical, and there might be cases where it is not
2855 # enough...
2856 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2857 }
2858
2859 # when user set globals, they would interfere with our calculation, so
2860 # disable them and later re-enable them
2861 no strict 'refs';
2862 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
2863 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
2864 # we also need to disable any set A or P on $x (_find_round_parameters took
2865 # them already into account), since these would interfere, too
2866 delete $x->{_a}; delete $x->{_p};
2867 # need to disable $upgrade in BigInt, to avoid deep recursion
2868 local $Math::BigInt::upgrade = undef;
2869
2870 my $last = 0;
2871 my $over = $x * $x; # X ^ 2
2872 my $x2 = $over->copy(); # X ^ 2; difference between terms
2873 $over->bmul($x); # X ^ 3 as starting value
2874 my $sign = 1; # start with -=
2875 my $below = $self->new(6); my $factorial = $self->new(4);
2876 delete $x->{_a}; delete $x->{_p};
2877
2878 my $limit = $self->new("1E-". ($scale-1));
2879 #my $steps = 0;
2880 while (3 < 5)
2881 {
2882 # we calculate the next term, and add it to the last
2883 # when the next term is below our limit, it won't affect the outcome
2884 # anymore, so we stop:
2885 my $next = $over->copy()->bdiv($below,$scale);
2886 last if $next->bacmp($limit) <= 0;
2887
2888 if ($sign == 0)
2889 {
2890 $x->badd($next);
2891 }
2892 else
2893 {
2894 $x->bsub($next);
2895 }
2896 $sign = 1-$sign; # alternate
2897 # calculate things for the next term
2898 $over->bmul($x2); # $x*$x
2899 $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2900 $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2901 }
2902
2903 # shortcut to not run through _find_round_parameters again
2904 if (defined $params[0])
2905 {
2906 $x->bround($params[0],$params[2]); # then round accordingly
2907 }
2908 else
2909 {
2910 $x->bfround($params[1],$params[2]); # then round accordingly
2911 }
2912 if ($fallback)
2913 {
2914 # clear a/p after round, since user did not request it
2915 delete $x->{_a}; delete $x->{_p};
2916 }
2917 # restore globals
2918 $$abr = $ab; $$pbr = $pb;
2919 $x;
2920 }
2921
2922sub batan2
2923 {
2924 # calculate arcus tangens of ($y/$x)
2925
2926 # set up parameters
2927 my ($self,$y,$x,@r) = (ref($_[0]),@_);
2928 # objectify is costly, so avoid it
2929 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
2930 {
2931 ($self,$y,$x,@r) = objectify(2,@_);
2932 }
2933
2934 return $y if $y->modify('batan2');
2935
2936 return $y->bnan() if ($y->{sign} eq $nan) || ($x->{sign} eq $nan);
2937
2938 # Y X
2939 # 0 0 result is 0
2940 # 0 +x result is 0
2941 # ? inf result is 0
2942 return $y->bzero(@r) if ($x->is_inf('+') && !$y->is_inf()) || ($y->is_zero() && $x->{sign} eq '+');
2943
2944 # Y X
2945 # != 0 -inf result is +- pi
2946 if ($x->is_inf() || $y->is_inf())
2947 {
2948 # calculate PI
2949 my $pi = $self->bpi(@r);
2950 if ($y->is_inf())
2951 {
2952 # upgrade to BigRat etc.
2953 return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
2954 if ($x->{sign} eq '-inf')
2955 {
2956 # calculate 3 pi/4
2957 $MBI->_mul($pi->{_m}, $MBI->_new(3));
2958 $MBI->_div($pi->{_m}, $MBI->_new(4));
2959 }
2960 elsif ($x->{sign} eq '+inf')
2961 {
2962 # calculate pi/4
2963 $MBI->_div($pi->{_m}, $MBI->_new(4));
2964 }
2965 else
2966 {
2967 # calculate pi/2
2968 $MBI->_div($pi->{_m}, $MBI->_new(2));
2969 }
2970 $y->{sign} = substr($y->{sign},0,1); # keep +/-
2971 }
2972 # modify $y in place
2973 $y->{_m} = $pi->{_m};
2974 $y->{_e} = $pi->{_e};
2975 $y->{_es} = $pi->{_es};
2976 # keep the sign of $y
2977 return $y;
2978 }
2979
2980 return $upgrade->new($y)->batan2($upgrade->new($x),@r) if defined $upgrade;
2981
2982 # Y X
2983 # 0 -x result is PI
2984 if ($y->is_zero())
2985 {
2986 # calculate PI
2987 my $pi = $self->bpi(@r);
2988 # modify $y in place
2989 $y->{_m} = $pi->{_m};
2990 $y->{_e} = $pi->{_e};
2991 $y->{_es} = $pi->{_es};
2992 $y->{sign} = '+';
2993 return $y;
2994 }
2995
2996 # Y X
2997 # +y 0 result is PI/2
2998 # -y 0 result is -PI/2
2999 if ($x->is_zero())
3000 {
3001 # calculate PI/2
3002 my $pi = $self->bpi(@r);
3003 # modify $y in place
3004 $y->{_m} = $pi->{_m};
3005 $y->{_e} = $pi->{_e};
3006 $y->{_es} = $pi->{_es};
3007 # -y => -PI/2, +y => PI/2
3008 $MBI->_div($y->{_m}, $MBI->_new(2));
3009 return $y;
3010 }
3011
3012 # we need to limit the accuracy to protect against overflow
3013 my $fallback = 0;
3014 my ($scale,@params);
3015 ($y,@params) = $y->_find_round_parameters(@r);
3016
3017 # error in _find_round_parameters?
3018 return $y if $y->is_nan();
3019
3020 # no rounding at all, so must use fallback
3021 if (scalar @params == 0)
3022 {
3023 # simulate old behaviour
3024 $params[0] = $self->div_scale(); # and round to it as accuracy
3025 $params[1] = undef; # disable P
3026 $scale = $params[0]+4; # at least four more for proper round
3027 $params[2] = $r[2]; # round mode by caller or undef
3028 $fallback = 1; # to clear a/p afterwards
3029 }
3030 else
3031 {
3032 # the 4 below is empirical, and there might be cases where it is not
3033 # enough...
3034 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
3035 }
3036
3037 # inlined is_one() && is_one('-')
3038 if ($MBI->_is_one($y->{_m}) && $MBI->_is_zero($y->{_e}))
3039 {
3040 # shortcut: 1 1 result is PI/4
3041 # inlined is_one() && is_one('-')
3042 if ($MBI->_is_one($x->{_m}) && $MBI->_is_zero($x->{_e}))
3043 {
3044 # 1,1 => PI/4
3045 my $pi_4 = $self->bpi( $scale - 3);
3046 # modify $y in place
3047 $y->{_m} = $pi_4->{_m};
3048 $y->{_e} = $pi_4->{_e};
3049 $y->{_es} = $pi_4->{_es};
3050 # 1 1 => +
3051 # -1 1 => -
3052 # 1 -1 => -
3053 # -1 -1 => +
3054 $y->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
3055 $MBI->_div($y->{_m}, $MBI->_new(4));
3056 return $y;
3057 }
3058 # shortcut: 1 int(X) result is _atan_inv(X)
3059
3060 # is integer
3061 if ($x->{_es} eq '+')
3062 {
3063 my $x1 = $MBI->_copy($x->{_m});
3064 $MBI->_lsft($x1, $x->{_e},10) unless $MBI->_is_zero($x->{_e});
3065
3066 my ($a,$b) = $self->_atan_inv($x1, $scale);
3067 my $y_sign = $y->{sign};
3068 # calculate A/B
3069 $y->bone(); $y->{_m} = $a; my $y_d = $self->bone(); $y_d->{_m} = $b;
3070 $y->bdiv($y_d, @r);
3071 $y->{sign} = $y_sign;
3072 return $y;
3073 }
3074 }
3075
3076 # handle all other cases
3077 # X Y
3078 # +x +y 0 to PI/2
3079 # -x +y PI/2 to PI
3080 # +x -y 0 to -PI/2
3081 # -x -y -PI/2 to -PI
3082
3083 my $y_sign = $y->{sign};
3084
3085 # divide $x by $y
3086 $y->bdiv($x, $scale) unless $x->is_one();
3087 $y->batan(@r);
3088
3089 # restore sign
3090 $y->{sign} = $y_sign;
3091
3092 $y;
3093 }
3094
3095sub batan
3096 {
3097 # Calculate a arcus tangens of x.
3098 my ($x,@r) = @_;
3099 my $self = ref($x);
3100
3101 # taylor: x^3 x^5 x^7 x^9
3102 # atan = x - --- + --- - --- + --- ...
3103 # 3 5 7 9
3104
3105 # we need to limit the accuracy to protect against overflow
3106 my $fallback = 0;
3107 my ($scale,@params);
3108 ($x,@params) = $x->_find_round_parameters(@r);
3109
3110 # constant object or error in _find_round_parameters?
3111 return $x if $x->modify('batan') || $x->is_nan();
3112
3113 if ($x->{sign} =~ /^[+-]inf\z/)
3114 {
3115 # +inf result is PI/2
3116 # -inf result is -PI/2
3117 # calculate PI/2
3118 my $pi = $self->bpi(@r);
3119 # modify $x in place
3120 $x->{_m} = $pi->{_m};
3121 $x->{_e} = $pi->{_e};
3122 $x->{_es} = $pi->{_es};
3123 # -y => -PI/2, +y => PI/2
3124 $x->{sign} = substr($x->{sign},0,1); # +inf => +
3125 $MBI->_div($x->{_m}, $MBI->_new(2));
3126 return $x;
3127 }
3128
3129 return $x->bzero(@r) if $x->is_zero();
3130
3131 # no rounding at all, so must use fallback
3132 if (scalar @params == 0)
3133 {
3134 # simulate old behaviour
3135 $params[0] = $self->div_scale(); # and round to it as accuracy
3136 $params[1] = undef; # disable P
3137 $scale = $params[0]+4; # at least four more for proper round
3138 $params[2] = $r[2]; # round mode by caller or undef
3139 $fallback = 1; # to clear a/p afterwards
3140 }
3141 else
3142 {
3143 # the 4 below is empirical, and there might be cases where it is not
3144 # enough...
3145 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
3146 }
3147
3148 # 1 or -1 => PI/4
3149 # inlined is_one() && is_one('-')
3150 if ($MBI->_is_one($x->{_m}) && $MBI->_is_zero($x->{_e}))
3151 {
3152 my $pi = $self->bpi($scale - 3);
3153 # modify $x in place
3154 $x->{_m} = $pi->{_m};
3155 $x->{_e} = $pi->{_e};
3156 $x->{_es} = $pi->{_es};
3157 # leave the sign of $x alone (+1 => +PI/4, -1 => -PI/4)
3158 $MBI->_div($x->{_m}, $MBI->_new(4));
3159 return $x;
3160 }
3161
3162 # This series is only valid if -1 < x < 1, so for other x we need to
3163 # to calculate PI/2 - atan(1/x):
3164 my $one = $MBI->_new(1);
3165 my $pi = undef;
3166 if ($x->{_es} eq '+' && ($MBI->_acmp($x->{_m},$one) >= 0))
3167 {
3168 # calculate PI/2
3169 $pi = $self->bpi($scale - 3);
3170 $MBI->_div($pi->{_m}, $MBI->_new(2));
3171 # calculate 1/$x:
3172 my $x_copy = $x->copy();
3173 # modify $x in place
3174 $x->bone(); $x->bdiv($x_copy,$scale);
3175 }
3176
3177 # when user set globals, they would interfere with our calculation, so
3178 # disable them and later re-enable them
3179 no strict 'refs';
3180 my $abr = "$self\::accuracy"; my $ab = $$abr; $$abr = undef;
3181 my $pbr = "$self\::precision"; my $pb = $$pbr; $$pbr = undef;
3182 # we also need to disable any set A or P on $x (_find_round_parameters took
3183 # them already into account), since these would interfere, too
3184 delete $x->{_a}; delete $x->{_p};
3185 # need to disable $upgrade in BigInt, to avoid deep recursion
3186 local $Math::BigInt::upgrade = undef;
3187
3188 my $last = 0;
3189 my $over = $x * $x; # X ^ 2
3190 my $x2 = $over->copy(); # X ^ 2; difference between terms
3191 $over->bmul($x); # X ^ 3 as starting value
3192 my $sign = 1; # start with -=
3193 my $below = $self->new(3);
3194 my $two = $self->new(2);
3195 delete $x->{_a}; delete $x->{_p};
3196
3197 my $limit = $self->new("1E-". ($scale-1));
3198 #my $steps = 0;
3199 while (3 < 5)
3200 {
3201 # we calculate the next term, and add it to the last
3202 # when the next term is below our limit, it won't affect the outcome
3203 # anymore, so we stop:
3204 my $next = $over->copy()->bdiv($below,$scale);
3205 last if $next->bacmp($limit) <= 0;
3206
3207 if ($sign == 0)
3208 {
3209 $x->badd($next);
3210 }
3211 else
3212 {
3213 $x->bsub($next);
3214 }
3215 $sign = 1-$sign; # alternate
3216 # calculate things for the next term
3217 $over->bmul($x2); # $x*$x
3218 $below->badd($two); # n += 2
3219 }
3220
3221 if (defined $pi)
3222 {
3223 my $x_copy = $x->copy();
3224 # modify $x in place
3225 $x->{_m} = $pi->{_m};
3226 $x->{_e} = $pi->{_e};
3227 $x->{_es} = $pi->{_es};
3228 # PI/2 - $x
3229 $x->bsub($x_copy);
3230 }
3231
3232 # shortcut to not run through _find_round_parameters again
3233 if (defined $params[0])
3234 {
3235 $x->bround($params[0],$params[2]); # then round accordingly
3236 }
3237 else
3238 {
3239 $x->bfround($params[1],$params[2]); # then round accordingly
3240 }
3241 if ($fallback)
3242 {
3243 # clear a/p after round, since user did not request it
3244 delete $x->{_a}; delete $x->{_p};
3245 }
3246 # restore globals
3247 $$abr = $ab; $$pbr = $pb;
3248 $x;
3249 }
3250
3251###############################################################################
3252# rounding functions
3253
3254sub bfround
3255 {
3256 # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
3257 # $n == 0 means round to integer
3258 # expects and returns normalized numbers!
3259 my $x = shift; my $self = ref($x) || $x; $x = $self->new(shift) if !ref($x);
3260
3261 my ($scale,$mode) = $x->_scale_p(@_);
3262 return $x if !defined $scale || $x->modify('bfround'); # no-op
3263
3264 # never round a 0, +-inf, NaN
3265 if ($x->is_zero())
3266 {
3267 $x->{_p} = $scale if !defined $x->{_p} || $x->{_p} < $scale; # -3 < -2
3268 return $x;
3269 }
3270 return $x if $x->{sign} !~ /^[+-]$/;
3271
3272 # don't round if x already has lower precision
3273 return $x if (defined $x->{_p} && $x->{_p} < 0 && $scale < $x->{_p});
3274
3275 $x->{_p} = $scale; # remember round in any case
3276 delete $x->{_a}; # and clear A
3277 if ($scale < 0)
3278 {
3279 # round right from the '.'
3280
3281 return $x if $x->{_es} eq '+'; # e >= 0 => nothing to round
3282
3283 $scale = -$scale; # positive for simplicity
3284 my $len = $MBI->_len($x->{_m}); # length of mantissa
3285
3286 # the following poses a restriction on _e, but if _e is bigger than a
3287 # scalar, you got other problems (memory etc) anyway
3288 my $dad = -(0+ ($x->{_es}.$MBI->_num($x->{_e}))); # digits after dot
3289 my $zad = 0; # zeros after dot
3290 $zad = $dad - $len if (-$dad < -$len); # for 0.00..00xxx style
3291
3292 # print "scale $scale dad $dad zad $zad len $len\n";
3293 # number bsstr len zad dad
3294 # 0.123 123e-3 3 0 3
3295 # 0.0123 123e-4 3 1 4
3296 # 0.001 1e-3 1 2 3
3297 # 1.23 123e-2 3 0 2
3298 # 1.2345 12345e-4 5 0 4
3299
3300 # do not round after/right of the $dad
3301 return $x if $scale > $dad; # 0.123, scale >= 3 => exit
3302
3303 # round to zero if rounding inside the $zad, but not for last zero like:
3304 # 0.0065, scale -2, round last '0' with following '65' (scale == zad case)
3305 return $x->bzero() if $scale < $zad;
3306 if ($scale == $zad) # for 0.006, scale -3 and trunc
3307 {
3308 $scale = -$len;
3309 }
3310 else
3311 {
3312 # adjust round-point to be inside mantissa
3313 if ($zad != 0)
3314 {
3315 $scale = $scale-$zad;
3316 }
3317 else
3318 {
3319 my $dbd = $len - $dad; $dbd = 0 if $dbd < 0; # digits before dot
3320 $scale = $dbd+$scale;
3321 }
3322 }
3323 }
3324 else
3325 {
3326 # round left from the '.'
3327
3328 # 123 => 100 means length(123) = 3 - $scale (2) => 1
3329
3330 my $dbt = $MBI->_len($x->{_m});
3331 # digits before dot
3332 my $dbd = $dbt + ($x->{_es} . $MBI->_num($x->{_e}));
3333 # should be the same, so treat it as this
3334 $scale = 1 if $scale == 0;
3335 # shortcut if already integer
3336 return $x if $scale == 1 && $dbt <= $dbd;
3337 # maximum digits before dot
3338 ++$dbd;
3339
3340 if ($scale > $dbd)
3341 {
3342 # not enough digits before dot, so round to zero
3343 return $x->bzero;
3344 }
3345 elsif ( $scale == $dbd )
3346 {
3347 # maximum
3348 $scale = -$dbt;
3349 }
3350 else
3351 {
3352 $scale = $dbd - $scale;
3353 }
3354 }
3355 # pass sign to bround for rounding modes '+inf' and '-inf'
3356 my $m = bless { sign => $x->{sign}, value => $x->{_m} }, 'Math::BigInt';
3357 $m->bround($scale,$mode);
3358 $x->{_m} = $m->{value}; # get our mantissa back
3359 $x->bnorm();
3360 }
3361
3362sub bround
3363 {
3364 # accuracy: preserve $N digits, and overwrite the rest with 0's
3365 my $x = shift; my $self = ref($x) || $x; $x = $self->new(shift) if !ref($x);
3366
3367 if (($_[0] || 0) < 0)
3368 {
3369 require Carp; Carp::croak ('bround() needs positive accuracy');
3370 }
3371
3372 my ($scale,$mode) = $x->_scale_a(@_);
3373 return $x if !defined $scale || $x->modify('bround'); # no-op
3374
3375 # scale is now either $x->{_a}, $accuracy, or the user parameter
3376 # test whether $x already has lower accuracy, do nothing in this case
3377 # but do round if the accuracy is the same, since a math operation might
3378 # want to round a number with A=5 to 5 digits afterwards again
3379 return $x if defined $x->{_a} && $x->{_a} < $scale;
3380
3381 # scale < 0 makes no sense
3382 # scale == 0 => keep all digits
3383 # never round a +-inf, NaN
3384 return $x if ($scale <= 0) || $x->{sign} !~ /^[+-]$/;
3385
3386 # 1: never round a 0
3387 # 2: if we should keep more digits than the mantissa has, do nothing
3388 if ($x->is_zero() || $MBI->_len($x->{_m}) <= $scale)
3389 {
3390 $x->{_a} = $scale if !defined $x->{_a} || $x->{_a} > $scale;
3391 return $x;
3392 }
3393
3394 # pass sign to bround for '+inf' and '-inf' rounding modes
3395 my $m = bless { sign => $x->{sign}, value => $x->{_m} }, 'Math::BigInt';
3396
3397 $m->bround($scale,$mode); # round mantissa
3398 $x->{_m} = $m->{value}; # get our mantissa back
3399 $x->{_a} = $scale; # remember rounding
3400 delete $x->{_p}; # and clear P
3401 $x->bnorm(); # del trailing zeros gen. by bround()
3402 }
3403
3404sub bfloor
3405 {
3406 # return integer less or equal then $x
3407 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
3408
3409 return $x if $x->modify('bfloor');
3410
3411 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
3412
3413 # if $x has digits after dot
3414 if ($x->{_es} eq '-')
3415 {
3416 $x->{_m} = $MBI->_rsft($x->{_m},$x->{_e},10); # cut off digits after dot
3417 $x->{_e} = $MBI->_zero(); # trunc/norm
3418 $x->{_es} = '+'; # abs e
3419 $MBI->_inc($x->{_m}) if $x->{sign} eq '-'; # increment if negative
3420 }
3421 $x->round($a,$p,$r);
3422 }
3423
3424sub bceil
3425 {
3426 # return integer greater or equal then $x
3427 my ($self,$x,$a,$p,$r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
3428
3429 return $x if $x->modify('bceil');
3430 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
3431
3432 # if $x has digits after dot
3433 if ($x->{_es} eq '-')
3434 {
3435 $x->{_m} = $MBI->_rsft($x->{_m},$x->{_e},10); # cut off digits after dot
3436 $x->{_e} = $MBI->_zero(); # trunc/norm
3437 $x->{_es} = '+'; # abs e
3438 $MBI->_inc($x->{_m}) if $x->{sign} eq '+'; # increment if positive
3439 }
3440 $x->round($a,$p,$r);
3441 }
3442
3443sub brsft
3444 {
3445 # shift right by $y (divide by power of $n)
3446
3447 # set up parameters
3448 my ($self,$x,$y,$n,$a,$p,$r) = (ref($_[0]),@_);
3449 # objectify is costly, so avoid it
3450 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
3451 {
3452 ($self,$x,$y,$n,$a,$p,$r) = objectify(2,@_);
3453 }
3454
3455 return $x if $x->modify('brsft');
3456 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
3457
3458 $n = 2 if !defined $n; $n = $self->new($n);
3459
3460 # negative amount?
3461 return $x->blsft($y->copy()->babs(),$n) if $y->{sign} =~ /^-/;
3462
3463 # the following call to bdiv() will return either quo or (quo,remainder):
3464 $x->bdiv($n->bpow($y),$a,$p,$r,$y);
3465 }
3466
3467sub blsft
3468 {
3469 # shift left by $y (multiply by power of $n)
3470
3471 # set up parameters
3472 my ($self,$x,$y,$n,$a,$p,$r) = (ref($_[0]),@_);
3473 # objectify is costly, so avoid it
3474 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
3475 {
3476 ($self,$x,$y,$n,$a,$p,$r) = objectify(2,@_);
3477 }
3478
3479 return $x if $x->modify('blsft');
3480 return $x if $x->{sign} !~ /^[+-]$/; # nan, +inf, -inf
3481
3482 $n = 2 if !defined $n; $n = $self->new($n);
3483
3484 # negative amount?
3485 return $x->brsft($y->copy()->babs(),$n) if $y->{sign} =~ /^-/;
3486
3487 $x->bmul($n->bpow($y),$a,$p,$r,$y);
3488 }
3489
3490###############################################################################
3491
3492sub DESTROY
3493 {
3494 # going through AUTOLOAD for every DESTROY is costly, avoid it by empty sub
3495 }
3496
3497sub AUTOLOAD
3498 {
3499 # make fxxx and bxxx both work by selectively mapping fxxx() to MBF::bxxx()
3500 # or falling back to MBI::bxxx()
3501 my $name = $AUTOLOAD;
3502
3503 $name =~ s/(.*):://; # split package
3504 my $c = $1 || $class;
3505 no strict 'refs';
3506 $c->import() if $IMPORT == 0;
3507 if (!_method_alias($name))
3508 {
3509 if (!defined $name)
3510 {
3511 # delayed load of Carp and avoid recursion
3512 require Carp;
3513 Carp::croak ("$c: Can't call a method without name");
3514 }
3515 if (!_method_hand_up($name))
3516 {
3517 # delayed load of Carp and avoid recursion
3518 require Carp;
3519 Carp::croak ("Can't call $c\-\>$name, not a valid method");
3520 }
3521 # try one level up, but subst. bxxx() for fxxx() since MBI only got bxxx()
3522 $name =~ s/^f/b/;
3523 return &{"Math::BigInt"."::$name"}(@_);
3524 }
3525 my $bname = $name; $bname =~ s/^f/b/;
3526 $c .= "::$name";
3527 *{$c} = \&{$bname};
3528 &{$c}; # uses @_
3529 }
3530
3531sub exponent
3532 {
3533 # return a copy of the exponent
3534 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3535
3536 if ($x->{sign} !~ /^[+-]$/)
3537 {
3538 my $s = $x->{sign}; $s =~ s/^[+-]//;
3539 return Math::BigInt->new($s); # -inf, +inf => +inf
3540 }
3541 Math::BigInt->new( $x->{_es} . $MBI->_str($x->{_e}));
3542 }
3543
3544sub mantissa
3545 {
3546 # return a copy of the mantissa
3547 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3548
3549 if ($x->{sign} !~ /^[+-]$/)
3550 {
3551 my $s = $x->{sign}; $s =~ s/^[+]//;
3552 return Math::BigInt->new($s); # -inf, +inf => +inf
3553 }
3554 my $m = Math::BigInt->new( $MBI->_str($x->{_m}));
3555 $m->bneg() if $x->{sign} eq '-';
3556
3557 $m;
3558 }
3559
3560sub parts
3561 {
3562 # return a copy of both the exponent and the mantissa
3563 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3564
3565 if ($x->{sign} !~ /^[+-]$/)
3566 {
3567 my $s = $x->{sign}; $s =~ s/^[+]//; my $se = $s; $se =~ s/^[-]//;
3568 return ($self->new($s),$self->new($se)); # +inf => inf and -inf,+inf => inf
3569 }
3570 my $m = Math::BigInt->bzero();
3571 $m->{value} = $MBI->_copy($x->{_m});
3572 $m->bneg() if $x->{sign} eq '-';
3573 ($m, Math::BigInt->new( $x->{_es} . $MBI->_num($x->{_e}) ));
3574 }
3575
3576##############################################################################
3577# private stuff (internal use only)
3578
3579sub import
3580 {
3581 my $self = shift;
3582 my $l = scalar @_;
3583 my $lib = ''; my @a;
3584 my $lib_kind = 'try';
3585 $IMPORT=1;
3586 for ( my $i = 0; $i < $l ; $i++)
3587 {
3588 if ( $_[$i] eq ':constant' )
3589 {
3590 # This causes overlord er load to step in. 'binary' and 'integer'
3591 # are handled by BigInt.
3592 overload::constant float => sub { $self->new(shift); };
3593 }
3594 elsif ($_[$i] eq 'upgrade')
3595 {
3596 # this causes upgrading
3597 $upgrade = $_[$i+1]; # or undef to disable
3598 $i++;
3599 }
3600 elsif ($_[$i] eq 'downgrade')
3601 {
3602 # this causes downgrading
3603 $downgrade = $_[$i+1]; # or undef to disable
3604 $i++;
3605 }
3606 elsif ($_[$i] =~ /^(lib|try|only)\z/)
3607 {
3608 # alternative library
3609 $lib = $_[$i+1] || ''; # default Calc
3610 $lib_kind = $1; # lib, try or only
3611 $i++;
3612 }
3613 elsif ($_[$i] eq 'with')
3614 {
3615 # alternative class for our private parts()
3616 # XXX: no longer supported
3617 # $MBI = $_[$i+1] || 'Math::BigInt';
3618 $i++;
3619 }
3620 else
3621 {
3622 push @a, $_[$i];
3623 }
3624 }
3625
3626 $lib =~ tr/a-zA-Z0-9,://cd; # restrict to sane characters
3627 # let use Math::BigInt lib => 'GMP'; use Math::BigFloat; still work
3628 my $mbilib = eval { Math::BigInt->config()->{lib} };
3629 if ((defined $mbilib) && ($MBI eq 'Math::BigInt::Calc'))
3630 {
3631 # MBI already loaded
3632 Math::BigInt->import( $lib_kind, "$lib,$mbilib", 'objectify');
3633 }
3634 else
3635 {
3636 # MBI not loaded, or with ne "Math::BigInt::Calc"
3637 $lib .= ",$mbilib" if defined $mbilib;
3638 $lib =~ s/^,//; # don't leave empty
3639
3640 # replacement library can handle lib statement, but also could ignore it
3641
3642 # Perl < 5.6.0 dies with "out of memory!" when eval() and ':constant' is
3643 # used in the same script, or eval inside import(). So we require MBI:
3644 require Math::BigInt;
3645 Math::BigInt->import( $lib_kind => $lib, 'objectify' );
3646 }
3647 if ($@)
3648 {
3649 require Carp; Carp::croak ("Couldn't load $lib: $! $@");
3650 }
3651 # find out which one was actually loaded
3652 $MBI = Math::BigInt->config()->{lib};
3653
3654 # register us with MBI to get notified of future lib changes
3655 Math::BigInt::_register_callback( $self, sub { $MBI = $_[0]; } );
3656
3657 $self->export_to_level(1,$self,@a); # export wanted functions
3658 }
3659
3660sub bnorm
3661 {
3662 # adjust m and e so that m is smallest possible
3663 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
3664
3665 return $x if $x->{sign} !~ /^[+-]$/; # inf, nan etc
3666
3667 my $zeros = $MBI->_zeros($x->{_m}); # correct for trailing zeros
3668 if ($zeros != 0)
3669 {
3670 my $z = $MBI->_new($zeros);
3671 $x->{_m} = $MBI->_rsft ($x->{_m}, $z, 10);
3672 if ($x->{_es} eq '-')
3673 {
3674 if ($MBI->_acmp($x->{_e},$z) >= 0)
3675 {
3676 $x->{_e} = $MBI->_sub ($x->{_e}, $z);
3677 $x->{_es} = '+' if $MBI->_is_zero($x->{_e});
3678 }
3679 else
3680 {
3681 $x->{_e} = $MBI->_sub ( $MBI->_copy($z), $x->{_e});
3682 $x->{_es} = '+';
3683 }
3684 }
3685 else
3686 {
3687 $x->{_e} = $MBI->_add ($x->{_e}, $z);
3688 }
3689 }
3690 else
3691 {
3692 # $x can only be 0Ey if there are no trailing zeros ('0' has 0 trailing
3693 # zeros). So, for something like 0Ey, set y to 1, and -0 => +0
3694 $x->{sign} = '+', $x->{_es} = '+', $x->{_e} = $MBI->_one()
3695 if $MBI->_is_zero($x->{_m});
3696 }
3697
3698 $x; # MBI bnorm is no-op, so do not call it
3699 }
3700
3701##############################################################################
3702
3703sub as_hex
3704 {
3705 # return number as hexadecimal string (only for integers defined)
3706 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3707
3708 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
3709 return '0x0' if $x->is_zero();
3710
3711 return $nan if $x->{_es} ne '+'; # how to do 1e-1 in hex!?
3712
3713 my $z = $MBI->_copy($x->{_m});
3714 if (! $MBI->_is_zero($x->{_e})) # > 0
3715 {
3716 $MBI->_lsft( $z, $x->{_e},10);
3717 }
3718 $z = Math::BigInt->new( $x->{sign} . $MBI->_num($z));
3719 $z->as_hex();
3720 }
3721
3722sub as_bin
3723 {
3724 # return number as binary digit string (only for integers defined)
3725 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3726
3727 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
3728 return '0b0' if $x->is_zero();
3729
3730 return $nan if $x->{_es} ne '+'; # how to do 1e-1 in hex!?
3731
3732 my $z = $MBI->_copy($x->{_m});
3733 if (! $MBI->_is_zero($x->{_e})) # > 0
3734 {
3735 $MBI->_lsft( $z, $x->{_e},10);
3736 }
3737 $z = Math::BigInt->new( $x->{sign} . $MBI->_num($z));
3738 $z->as_bin();
3739 }
3740
3741sub as_oct
3742 {
3743 # return number as octal digit string (only for integers defined)
3744 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3745
3746 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
3747 return '0' if $x->is_zero();
3748
3749 return $nan if $x->{_es} ne '+'; # how to do 1e-1 in hex!?
3750
3751 my $z = $MBI->_copy($x->{_m});
3752 if (! $MBI->_is_zero($x->{_e})) # > 0
3753 {
3754 $MBI->_lsft( $z, $x->{_e},10);
3755 }
3756 $z = Math::BigInt->new( $x->{sign} . $MBI->_num($z));
3757 $z->as_oct();
3758 }
3759
3760sub as_number
3761 {
3762 # return copy as a bigint representation of this BigFloat number
3763 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
3764
3765 return $x if $x->modify('as_number');
3766
3767 if (!$x->isa('Math::BigFloat'))
3768 {
3769 # if the object can as_number(), use it
3770 return $x->as_number() if $x->can('as_number');
3771 # otherwise, get us a float and then a number
3772 $x = $x->can('as_float') ? $x->as_float() : $self->new(0+"$x");
3773 }
3774
3775 return Math::BigInt->binf($x->sign()) if $x->is_inf();
3776 return Math::BigInt->bnan() if $x->is_nan();
3777
3778 my $z = $MBI->_copy($x->{_m});
3779 if ($x->{_es} eq '-') # < 0
3780 {
3781 $MBI->_rsft( $z, $x->{_e},10);
3782 }
3783 elsif (! $MBI->_is_zero($x->{_e})) # > 0
3784 {
3785 $MBI->_lsft( $z, $x->{_e},10);
3786 }
3787 $z = Math::BigInt->new( $x->{sign} . $MBI->_str($z));
3788 $z;
3789 }
3790
3791sub length
3792 {
3793 my $x = shift;
3794 my $class = ref($x) || $x;
3795 $x = $class->new(shift) unless ref($x);
3796
3797 return 1 if $MBI->_is_zero($x->{_m});
3798
3799 my $len = $MBI->_len($x->{_m});
3800 $len += $MBI->_num($x->{_e}) if $x->{_es} eq '+';
3801 if (wantarray())
3802 {
3803 my $t = 0;
3804 $t = $MBI->_num($x->{_e}) if $x->{_es} eq '-';
3805 return ($len, $t);
3806 }
3807 $len;
3808 }
3809
38101;
3811
3812__END__
3813
3814=head1 NAME
3815
3816Math::BigFloat - Arbitrary size floating point math package
3817
3818=head1 SYNOPSIS
3819
3820 use Math::BigFloat;
3821
3822 # Number creation
3823 my $x = Math::BigFloat->new($str); # defaults to 0
3824 my $y = $x->copy(); # make a true copy
3825 my $nan = Math::BigFloat->bnan(); # create a NotANumber
3826 my $zero = Math::BigFloat->bzero(); # create a +0
3827 my $inf = Math::BigFloat->binf(); # create a +inf
3828 my $inf = Math::BigFloat->binf('-'); # create a -inf
3829 my $one = Math::BigFloat->bone(); # create a +1
3830 my $mone = Math::BigFloat->bone('-'); # create a -1
3831
3832 my $pi = Math::BigFloat->bpi(100); # PI to 100 digits
3833
3834 # the following examples compute their result to 100 digits accuracy:
3835 my $cos = Math::BigFloat->new(1)->bcos(100); # cosinus(1)
3836 my $sin = Math::BigFloat->new(1)->bsin(100); # sinus(1)
3837 my $atan = Math::BigFloat->new(1)->batan(100); # arcus tangens(1)
3838
3839 my $atan2 = Math::BigFloat->new( 1 )->batan2( 1 ,100); # batan(1)
3840 my $atan2 = Math::BigFloat->new( 1 )->batan2( 8 ,100); # batan(1/8)
3841 my $atan2 = Math::BigFloat->new( -2 )->batan2( 1 ,100); # batan(-2)
3842
3843 # Testing
3844 $x->is_zero(); # true if arg is +0
3845 $x->is_nan(); # true if arg is NaN
3846 $x->is_one(); # true if arg is +1
3847 $x->is_one('-'); # true if arg is -1
3848 $x->is_odd(); # true if odd, false for even
3849 $x->is_even(); # true if even, false for odd
3850 $x->is_pos(); # true if >= 0
3851 $x->is_neg(); # true if < 0
3852 $x->is_inf(sign); # true if +inf, or -inf (default is '+')
3853
3854 $x->bcmp($y); # compare numbers (undef,<0,=0,>0)
3855 $x->bacmp($y); # compare absolutely (undef,<0,=0,>0)
3856 $x->sign(); # return the sign, either +,- or NaN
3857 $x->digit($n); # return the nth digit, counting from right
3858 $x->digit(-$n); # return the nth digit, counting from left
3859
3860 # The following all modify their first argument. If you want to pre-
3861 # serve $x, use $z = $x->copy()->bXXX($y); See under L</CAVEATS> for
3862 # necessary when mixing $a = $b assignments with non-overloaded math.
3863
3864 # set
3865 $x->bzero(); # set $i to 0
3866 $x->bnan(); # set $i to NaN
3867 $x->bone(); # set $x to +1
3868 $x->bone('-'); # set $x to -1
3869 $x->binf(); # set $x to inf
3870 $x->binf('-'); # set $x to -inf
3871
3872 $x->bneg(); # negation
3873 $x->babs(); # absolute value
3874 $x->bnorm(); # normalize (no-op)
3875 $x->bnot(); # two's complement (bit wise not)
3876 $x->binc(); # increment x by 1
3877 $x->bdec(); # decrement x by 1
3878
3879 $x->badd($y); # addition (add $y to $x)
3880 $x->bsub($y); # subtraction (subtract $y from $x)
3881 $x->bmul($y); # multiplication (multiply $x by $y)
3882 $x->bdiv($y); # divide, set $x to quotient
3883 # return (quo,rem) or quo if scalar
3884
3885 $x->bmod($y); # modulus ($x % $y)
3886 $x->bpow($y); # power of arguments ($x ** $y)
3887 $x->bmodpow($exp,$mod); # modular exponentiation (($num**$exp) % $mod))
3888 $x->blsft($y, $n); # left shift by $y places in base $n
3889 $x->brsft($y, $n); # right shift by $y places in base $n
3890 # returns (quo,rem) or quo if in scalar context
3891
3892 $x->blog(); # logarithm of $x to base e (Euler's number)
3893 $x->blog($base); # logarithm of $x to base $base (f.i. 2)
3894 $x->bexp(); # calculate e ** $x where e is Euler's number
3895
3896 $x->band($y); # bit-wise and
3897 $x->bior($y); # bit-wise inclusive or
3898 $x->bxor($y); # bit-wise exclusive or
3899 $x->bnot(); # bit-wise not (two's complement)
3900
3901 $x->bsqrt(); # calculate square-root
3902 $x->broot($y); # $y'th root of $x (e.g. $y == 3 => cubic root)
3903 $x->bfac(); # factorial of $x (1*2*3*4*..$x)
3904
3905 $x->bround($N); # accuracy: preserve $N digits
3906 $x->bfround($N); # precision: round to the $Nth digit
3907
3908 $x->bfloor(); # return integer less or equal than $x
3909 $x->bceil(); # return integer greater or equal than $x
3910
3911 # The following do not modify their arguments:
3912
3913 bgcd(@values); # greatest common divisor
3914 blcm(@values); # lowest common multiplicator
3915
3916 $x->bstr(); # return string
3917 $x->bsstr(); # return string in scientific notation
3918
3919 $x->as_int(); # return $x as BigInt
3920 $x->exponent(); # return exponent as BigInt
3921 $x->mantissa(); # return mantissa as BigInt
3922 $x->parts(); # return (mantissa,exponent) as BigInt
3923
3924 $x->length(); # number of digits (w/o sign and '.')
3925 ($l,$f) = $x->length(); # number of digits, and length of fraction
3926
3927 $x->precision(); # return P of $x (or global, if P of $x undef)
3928 $x->precision($n); # set P of $x to $n
3929 $x->accuracy(); # return A of $x (or global, if A of $x undef)
3930 $x->accuracy($n); # set A $x to $n
3931
3932 # these get/set the appropriate global value for all BigFloat objects
3933 Math::BigFloat->precision(); # Precision
3934 Math::BigFloat->accuracy(); # Accuracy
3935 Math::BigFloat->round_mode(); # rounding mode
3936
3937=head1 DESCRIPTION
3938
3939All operators (including basic math operations) are overloaded if you
3940declare your big floating point numbers as
3941
3942 $i = new Math::BigFloat '12_3.456_789_123_456_789E-2';
3943
3944Operations with overloaded operators preserve the arguments, which is
3945exactly what you expect.
3946
3947=head2 Input
3948
3949Input to these routines are either BigFloat objects, or strings of the
3950following four forms:
3951
3952=over
3953
3954=item *
3955
3956C</^[+-]\d+$/>
3957
3958=item *
3959
3960C</^[+-]\d+\.\d*$/>
3961
3962=item *
3963
3964C</^[+-]\d+E[+-]?\d+$/>
3965
3966=item *
3967
3968C</^[+-]\d*\.\d+E[+-]?\d+$/>
3969
3970=back
3971
3972all with optional leading and trailing zeros and/or spaces. Additionally,
3973numbers are allowed to have an underscore between any two digits.
3974
3975Empty strings as well as other illegal numbers results in 'NaN'.
3976
3977bnorm() on a BigFloat object is now effectively a no-op, since the numbers
3978are always stored in normalized form. On a string, it creates a BigFloat
3979object.
3980
3981=head2 Output
3982
3983Output values are BigFloat objects (normalized), except for bstr() and bsstr().
3984
3985The string output will always have leading and trailing zeros stripped and drop
3986a plus sign. C<bstr()> will give you always the form with a decimal point,
3987while C<bsstr()> (s for scientific) gives you the scientific notation.
3988
3989 Input bstr() bsstr()
3990 '-0' '0' '0E1'
3991 ' -123 123 123' '-123123123' '-123123123E0'
3992 '00.0123' '0.0123' '123E-4'
3993 '123.45E-2' '1.2345' '12345E-4'
3994 '10E+3' '10000' '1E4'
3995
3996Some routines (C<is_odd()>, C<is_even()>, C<is_zero()>, C<is_one()>,
3997C<is_nan()>) return true or false, while others (C<bcmp()>, C<bacmp()>)
3998return either undef, <0, 0 or >0 and are suited for sort.
3999
4000Actual math is done by using the class defined with C<< with => Class; >>
4001(which defaults to BigInts) to represent the mantissa and exponent.
4002
4003The sign C</^[+-]$/> is stored separately. The string 'NaN' is used to
4004represent the result when input arguments are not numbers, as well as
4005the result of dividing by zero.
4006
4007=head2 mantissa(), exponent() and parts()
4008
4009mantissa() and exponent() return the said parts of the BigFloat
4010as BigInts such that:
4011
4012 $m = $x->mantissa();
4013 $e = $x->exponent();
4014 $y = $m * ( 10 ** $e );
4015 print "ok\n" if $x == $y;
4016
4017C<< ($m,$e) = $x->parts(); >> is just a shortcut giving you both of them.
4018
4019A zero is represented and returned as C<0E1>, B<not> C<0E0> (after Knuth).
4020
4021Currently the mantissa is reduced as much as possible, favouring higher
4022exponents over lower ones (e.g. returning 1e7 instead of 10e6 or 10000000e0).
4023This might change in the future, so do not depend on it.
4024
4025=head2 Accuracy vs. Precision
4026
4027See also: L<Rounding|/Rounding>.
4028
4029Math::BigFloat supports both precision (rounding to a certain place before or
4030after the dot) and accuracy (rounding to a certain number of digits). For a
4031full documentation, examples and tips on these topics please see the large
4032section about rounding in L<Math::BigInt>.
4033
4034Since things like C<sqrt(2)> or C<1 / 3> must presented with a limited
4035accuracy lest a operation consumes all resources, each operation produces
4036no more than the requested number of digits.
4037
4038If there is no global precision or accuracy set, B<and> the operation in
4039question was not called with a requested precision or accuracy, B<and> the
4040input $x has no accuracy or precision set, then a fallback parameter will
4041be used. For historical reasons, it is called C<div_scale> and can be accessed
4042via:
4043
4044 $d = Math::BigFloat->div_scale(); # query
4045 Math::BigFloat->div_scale($n); # set to $n digits
4046
4047The default value for C<div_scale> is 40.
4048
4049In case the result of one operation has more digits than specified,
4050it is rounded. The rounding mode taken is either the default mode, or the one
4051supplied to the operation after the I<scale>:
4052
4053 $x = Math::BigFloat->new(2);
4054 Math::BigFloat->accuracy(5); # 5 digits max
4055 $y = $x->copy()->bdiv(3); # will give 0.66667
4056 $y = $x->copy()->bdiv(3,6); # will give 0.666667
4057 $y = $x->copy()->bdiv(3,6,undef,'odd'); # will give 0.666667
4058 Math::BigFloat->round_mode('zero');
4059 $y = $x->copy()->bdiv(3,6); # will also give 0.666667
4060
4061Note that C<< Math::BigFloat->accuracy() >> and C<< Math::BigFloat->precision() >>
4062set the global variables, and thus B<any> newly created number will be subject
4063to the global rounding B<immediately>. This means that in the examples above, the
4064C<3> as argument to C<bdiv()> will also get an accuracy of B<5>.
4065
4066It is less confusing to either calculate the result fully, and afterwards
4067round it explicitly, or use the additional parameters to the math
4068functions like so:
4069
4070 use Math::BigFloat;
4071 $x = Math::BigFloat->new(2);
4072 $y = $x->copy()->bdiv(3);
4073 print $y->bround(5),"\n"; # will give 0.66667
4074
4075 or
4076
4077 use Math::BigFloat;
4078 $x = Math::BigFloat->new(2);
4079 $y = $x->copy()->bdiv(3,5); # will give 0.66667
4080 print "$y\n";
4081
4082=head2 Rounding
4083
4084=over
4085
4086=item ffround ( +$scale )
4087
4088Rounds to the $scale'th place left from the '.', counting from the dot.
4089The first digit is numbered 1.
4090
4091=item ffround ( -$scale )
4092
4093Rounds to the $scale'th place right from the '.', counting from the dot.
4094
4095=item ffround ( 0 )
4096
4097Rounds to an integer.
4098
4099=item fround ( +$scale )
4100
4101Preserves accuracy to $scale digits from the left (aka significant digits)
4102and pads the rest with zeros. If the number is between 1 and -1, the
4103significant digits count from the first non-zero after the '.'
4104
4105=item fround ( -$scale ) and fround ( 0 )
4106
4107These are effectively no-ops.
4108
4109=back
4110
4111All rounding functions take as a second parameter a rounding mode from one of
4112the following: 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'.
4113
4114The default rounding mode is 'even'. By using
4115C<< Math::BigFloat->round_mode($round_mode); >> you can get and set the default
4116mode for subsequent rounding. The usage of C<$Math::BigFloat::$round_mode> is
4117no longer supported.
4118The second parameter to the round functions then overrides the default
4119temporarily.
4120
4121The C<as_number()> function returns a BigInt from a Math::BigFloat. It uses
4122'trunc' as rounding mode to make it equivalent to:
4123
4124 $x = 2.5;
4125 $y = int($x) + 2;
4126
4127You can override this by passing the desired rounding mode as parameter to
4128C<as_number()>:
4129
4130 $x = Math::BigFloat->new(2.5);
4131 $y = $x->as_number('odd'); # $y = 3
4132
4133=head1 METHODS
4134
4135Math::BigFloat supports all methods that Math::BigInt supports, except it
4136calculates non-integer results when possible. Please see L<Math::BigInt>
4137for a full description of each method. Below are just the most important
4138differences:
4139
4140=over
4141
4142=item accuracy()
4143
4144 $x->accuracy(5); # local for $x
4145 CLASS->accuracy(5); # global for all members of CLASS
4146 # Note: This also applies to new()!
4147
4148 $A = $x->accuracy(); # read out accuracy that affects $x
4149 $A = CLASS->accuracy(); # read out global accuracy
4150
4151Set or get the global or local accuracy, aka how many significant digits the
4152results have. If you set a global accuracy, then this also applies to new()!
4153
4154Warning! The accuracy I<sticks>, e.g. once you created a number under the
4155influence of C<< CLASS->accuracy($A) >>, all results from math operations with
4156that number will also be rounded.
4157
4158In most cases, you should probably round the results explicitly using one of
4159L<Math::BigInt/round()>, L<Math::BigInt/bround()> or L<Math::BigInt/bfround()> or by passing the desired accuracy
4160to the math operation as additional parameter:
4161
4162 my $x = Math::BigInt->new(30000);
4163 my $y = Math::BigInt->new(7);
4164 print scalar $x->copy()->bdiv($y, 2); # print 4300
4165 print scalar $x->copy()->bdiv($y)->bround(2); # print 4300
4166
4167=item precision()
4168
4169 $x->precision(-2); # local for $x, round at the second
4170 # digit right of the dot
4171 $x->precision(2); # ditto, round at the second digit left
4172 # of the dot
4173
4174 CLASS->precision(5); # Global for all members of CLASS
4175 # This also applies to new()!
4176 CLASS->precision(-5); # ditto
4177
4178 $P = CLASS->precision(); # read out global precision
4179 $P = $x->precision(); # read out precision that affects $x
4180
4181Note: You probably want to use L</accuracy()> instead. With L</accuracy()> you
4182set the number of digits each result should have, with L</precision()> you
4183set the place where to round!
4184
4185=item bexp()
4186
4187 $x->bexp($accuracy); # calculate e ** X
4188
4189Calculates the expression C<e ** $x> where C<e> is Euler's number.
4190
4191This method was added in v1.82 of Math::BigInt (April 2007).
4192
4193=item bnok()
4194
4195 $x->bnok($y); # x over y (binomial coefficient n over k)
4196
4197Calculates the binomial coefficient n over k, also called the "choose"
4198function. The result is equivalent to:
4199
4200 ( n ) n!
4201 | - | = -------
4202 ( k ) k!(n-k)!
4203
4204This method was added in v1.84 of Math::BigInt (April 2007).
4205
4206=item bpi()
4207
4208 print Math::BigFloat->bpi(100), "\n";
4209
4210Calculate PI to N digits (including the 3 before the dot). The result is
4211rounded according to the current rounding mode, which defaults to "even".
4212
4213This method was added in v1.87 of Math::BigInt (June 2007).
4214
4215=item bcos()
4216
4217 my $x = Math::BigFloat->new(1);
4218 print $x->bcos(100), "\n";
4219
4220Calculate the cosinus of $x, modifying $x in place.
4221
4222This method was added in v1.87 of Math::BigInt (June 2007).
4223
4224=item bsin()
4225
4226 my $x = Math::BigFloat->new(1);
4227 print $x->bsin(100), "\n";
4228
4229Calculate the sinus of $x, modifying $x in place.
4230
4231This method was added in v1.87 of Math::BigInt (June 2007).
4232
4233=item batan2()
4234
4235 my $y = Math::BigFloat->new(2);
4236 my $x = Math::BigFloat->new(3);
4237 print $y->batan2($x), "\n";
4238
4239Calculate the arcus tanges of C<$y> divided by C<$x>, modifying $y in place.
4240See also L</batan()>.
4241
4242This method was added in v1.87 of Math::BigInt (June 2007).
4243
4244=item batan()
4245
4246 my $x = Math::BigFloat->new(1);
4247 print $x->batan(100), "\n";
4248
4249Calculate the arcus tanges of $x, modifying $x in place. See also L</batan2()>.
4250
4251This method was added in v1.87 of Math::BigInt (June 2007).
4252
4253=item bmuladd()
4254
4255 $x->bmuladd($y,$z);
4256
4257Multiply $x by $y, and then add $z to the result.
4258
4259This method was added in v1.87 of Math::BigInt (June 2007).
4260
4261=back
4262
4263=head1 Autocreating constants
4264
4265After C<use Math::BigFloat ':constant'> all the floating point constants
4266in the given scope are converted to C<Math::BigFloat>. This conversion
4267happens at compile time.
4268
4269In particular
4270
4271 perl -MMath::BigFloat=:constant -e 'print 2E-100,"\n"'
4272
4273prints the value of C<2E-100>. Note that without conversion of
4274constants the expression 2E-100 will be calculated as normal floating point
4275number.
4276
4277Please note that ':constant' does not affect integer constants, nor binary
4278nor hexadecimal constants. Use L<bignum> or L<Math::BigInt> to get this to
4279work.
4280
4281=head2 Math library
4282
4283Math with the numbers is done (by default) by a module called
4284Math::BigInt::Calc. This is equivalent to saying:
4285
4286 use Math::BigFloat lib => 'Calc';
4287
4288You can change this by using:
4289
4290 use Math::BigFloat lib => 'GMP';
4291
4292B<Note>: General purpose packages should not be explicit about the library
4293to use; let the script author decide which is best.
4294
4295Note: The keyword 'lib' will warn when the requested library could not be
4296loaded. To suppress the warning use 'try' instead:
4297
4298 use Math::BigFloat try => 'GMP';
4299
4300If your script works with huge numbers and Calc is too slow for them,
4301you can also for the loading of one of these libraries and if none
4302of them can be used, the code will die:
4303
4304 use Math::BigFloat only => 'GMP,Pari';
4305
4306The following would first try to find Math::BigInt::Foo, then
4307Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
4308
4309 use Math::BigFloat lib => 'Foo,Math::BigInt::Bar';
4310
4311See the respective low-level library documentation for further details.
4312
4313Please note that Math::BigFloat does B<not> use the denoted library itself,
4314but it merely passes the lib argument to Math::BigInt. So, instead of the need
4315to do:
4316
4317 use Math::BigInt lib => 'GMP';
4318 use Math::BigFloat;
4319
4320you can roll it all into one line:
4321
4322 use Math::BigFloat lib => 'GMP';
4323
4324It is also possible to just require Math::BigFloat:
4325
4326 require Math::BigFloat;
4327
4328This will load the necessary things (like BigInt) when they are needed, and
4329automatically.
4330
4331See L<Math::BigInt> for more details than you ever wanted to know about using
4332a different low-level library.
4333
4334=head2 Using Math::BigInt::Lite
4335
4336For backwards compatibility reasons it is still possible to
4337request a different storage class for use with Math::BigFloat:
4338
4339 use Math::BigFloat with => 'Math::BigInt::Lite';
4340
4341However, this request is ignored, as the current code now uses the low-level
4342math library for directly storing the number parts.
4343
4344=head1 EXPORTS
4345
4346C<Math::BigFloat> exports nothing by default, but can export the C<bpi()> method:
4347
4348 use Math::BigFloat qw/bpi/;
4349
4350 print bpi(10), "\n";
4351
4352=head1 BUGS
4353
4354Please see the file BUGS in the CPAN distribution Math::BigInt for known bugs.
4355
4356=head1 CAVEATS
4357
4358Do not try to be clever to insert some operations in between switching
4359libraries:
4360
4361 require Math::BigFloat;
4362 my $matter = Math::BigFloat->bone() + 4; # load BigInt and Calc
4363 Math::BigFloat->import( lib => 'Pari' ); # load Pari, too
4364 my $anti_matter = Math::BigFloat->bone()+4; # now use Pari
4365
4366This will create objects with numbers stored in two different backend libraries,
4367and B<VERY BAD THINGS> will happen when you use these together:
4368
4369 my $flash_and_bang = $matter + $anti_matter; # Don't do this!
4370
4371=over
4372
4373=item stringify, bstr()
4374
4375Both stringify and bstr() now drop the leading '+'. The old code would return
4376'+1.23', the new returns '1.23'. See the documentation in L<Math::BigInt> for
4377reasoning and details.
4378
4379=item bdiv()
4380
4381The following will probably not print what you expect:
4382
4383 print $c->bdiv(123.456),"\n";
4384
4385It prints both quotient and remainder since print works in list context. Also,
4386bdiv() will modify $c, so be careful. You probably want to use
4387
4388 print $c / 123.456,"\n";
4389 print scalar $c->bdiv(123.456),"\n"; # or if you want to modify $c
4390
4391instead.
4392
4393=item brsft()
4394
4395The following will probably not print what you expect:
4396
4397 my $c = Math::BigFloat->new('3.14159');
4398 print $c->brsft(3,10),"\n"; # prints 0.00314153.1415
4399
4400It prints both quotient and remainder, since print calls C<brsft()> in list
4401context. Also, C<< $c->brsft() >> will modify $c, so be careful.
4402You probably want to use
4403
4404 print scalar $c->copy()->brsft(3,10),"\n";
4405 # or if you really want to modify $c
4406 print scalar $c->brsft(3,10),"\n";
4407
4408instead.
4409
4410=item Modifying and =
4411
4412Beware of:
4413
4414 $x = Math::BigFloat->new(5);
4415 $y = $x;
4416
4417It will not do what you think, e.g. making a copy of $x. Instead it just makes
4418a second reference to the B<same> object and stores it in $y. Thus anything
4419that modifies $x will modify $y (except overloaded math operators), and vice
4420versa. See L<Math::BigInt> for details and how to avoid that.
4421
4422=item bpow()
4423
4424C<bpow()> now modifies the first argument, unlike the old code which left
4425it alone and only returned the result. This is to be consistent with
4426C<badd()> etc. The first will modify $x, the second one won't:
4427
4428 print bpow($x,$i),"\n"; # modify $x
4429 print $x->bpow($i),"\n"; # ditto
4430 print $x ** $i,"\n"; # leave $x alone
4431
4432=item precision() vs. accuracy()
4433
4434A common pitfall is to use L</precision()> when you want to round a result to
4435a certain number of digits:
4436
4437 use Math::BigFloat;
4438
4439 Math::BigFloat->precision(4); # does not do what you
4440 # think it does
4441 my $x = Math::BigFloat->new(12345); # rounds $x to "12000"!
4442 print "$x\n"; # print "12000"
4443 my $y = Math::BigFloat->new(3); # rounds $y to "0"!
4444 print "$y\n"; # print "0"
4445 $z = $x / $y; # 12000 / 0 => NaN!
4446 print "$z\n";
4447 print $z->precision(),"\n"; # 4
4448
4449Replacing L</precision()> with L</accuracy()> is probably not what you want, either:
4450
4451 use Math::BigFloat;
4452
4453 Math::BigFloat->accuracy(4); # enables global rounding:
4454 my $x = Math::BigFloat->new(123456); # rounded immediately
4455 # to "12350"
4456 print "$x\n"; # print "123500"
4457 my $y = Math::BigFloat->new(3); # rounded to "3
4458 print "$y\n"; # print "3"
4459 print $z = $x->copy()->bdiv($y),"\n"; # 41170
4460 print $z->accuracy(),"\n"; # 4
4461
4462What you want to use instead is:
4463
4464 use Math::BigFloat;
4465
4466 my $x = Math::BigFloat->new(123456); # no rounding
4467 print "$x\n"; # print "123456"
4468 my $y = Math::BigFloat->new(3); # no rounding
4469 print "$y\n"; # print "3"
4470 print $z = $x->copy()->bdiv($y,4),"\n"; # 41150
4471 print $z->accuracy(),"\n"; # undef
4472
4473In addition to computing what you expected, the last example also does B<not>
4474"taint" the result with an accuracy or precision setting, which would
4475influence any further operation.
4476
4477=back
4478
4479=head1 SEE ALSO
4480
4481L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well as
4482L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
4483
4484The pragmas L<bignum>, L<bigint> and L<bigrat> might also be of interest
4485because they solve the autoupgrading/downgrading issue, at least partly.
4486
4487The package at L<http://search.cpan.org/~tels/Math-BigInt> contains
4488more documentation including a full version history, testcases, empty
4489subclass files and benchmarks.
4490
4491=head1 LICENSE
4492
4493This program is free software; you may redistribute it and/or modify it under
4494the same terms as Perl itself.
4495
4496=head1 AUTHORS
4497
4498Mark Biggar, overloaded interface by Ilya Zakharevich.
4499Completely rewritten by Tels L<http://bloodgate.com> in 2001 - 2006, and still
4500at it in 2007.
4501
4502=cut