xref: /openbsd-src/gnu/usr.bin/perl/cpan/Math-BigInt/lib/Math/BigFloat.pm (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
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 used internally:
8# sign  : "+", "-", "+inf", "-inf", or "NaN" if not a number
9#   _m  : mantissa ($LIB thingy)
10#   _es : sign of _e
11#   _e  : exponent ($LIB thingy)
12#   _a  : accuracy
13#   _p  : precision
14
15use 5.006001;
16use strict;
17use warnings;
18
19use Carp          qw< carp croak >;
20use Scalar::Util  qw< blessed >;
21use Math::BigInt  qw< >;
22
23our $VERSION = '1.999830';
24$VERSION =~ tr/_//d;
25
26require Exporter;
27our @ISA        = qw/Math::BigInt/;
28our @EXPORT_OK  = qw/bpi/;
29
30# $_trap_inf/$_trap_nan are internal and should never be accessed from outside
31our ($AUTOLOAD, $accuracy, $precision, $div_scale, $round_mode, $rnd_mode,
32     $upgrade, $downgrade, $_trap_nan, $_trap_inf);
33
34use overload
35
36  # overload key: with_assign
37
38  '+'     =>      sub { $_[0] -> copy() -> badd($_[1]); },
39
40  '-'     =>      sub { my $c = $_[0] -> copy();
41                        $_[2] ? $c -> bneg() -> badd($_[1])
42                              : $c -> bsub($_[1]); },
43
44  '*'     =>      sub { $_[0] -> copy() -> bmul($_[1]); },
45
46  '/'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bdiv($_[0])
47                              : $_[0] -> copy() -> bdiv($_[1]); },
48
49  '%'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bmod($_[0])
50                              : $_[0] -> copy() -> bmod($_[1]); },
51
52  '**'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bpow($_[0])
53                              : $_[0] -> copy() -> bpow($_[1]); },
54
55  '<<'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> blsft($_[0])
56                              : $_[0] -> copy() -> blsft($_[1]); },
57
58  '>>'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> brsft($_[0])
59                              : $_[0] -> copy() -> brsft($_[1]); },
60
61  # overload key: assign
62
63  '+='    =>      sub { $_[0] -> badd($_[1]); },
64
65  '-='    =>      sub { $_[0] -> bsub($_[1]); },
66
67  '*='    =>      sub { $_[0] -> bmul($_[1]); },
68
69  '/='    =>      sub { scalar $_[0] -> bdiv($_[1]); },
70
71  '%='    =>      sub { $_[0] -> bmod($_[1]); },
72
73  '**='   =>      sub { $_[0] -> bpow($_[1]); },
74
75  '<<='   =>      sub { $_[0] -> blsft($_[1]); },
76
77  '>>='   =>      sub { $_[0] -> brsft($_[1]); },
78
79#  'x='    =>      sub { },
80
81#  '.='    =>      sub { },
82
83  # overload key: num_comparison
84
85  '<'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> blt($_[0])
86                              : $_[0] -> blt($_[1]); },
87
88  '<='    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> ble($_[0])
89                              : $_[0] -> ble($_[1]); },
90
91  '>'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bgt($_[0])
92                              : $_[0] -> bgt($_[1]); },
93
94  '>='    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bge($_[0])
95                              : $_[0] -> bge($_[1]); },
96
97  '=='    =>      sub { $_[0] -> beq($_[1]); },
98
99  '!='    =>      sub { $_[0] -> bne($_[1]); },
100
101  # overload key: 3way_comparison
102
103  '<=>'   =>      sub { my $cmp = $_[0] -> bcmp($_[1]);
104                        defined($cmp) && $_[2] ? -$cmp : $cmp; },
105
106  'cmp'   =>      sub { $_[2] ? "$_[1]" cmp $_[0] -> bstr()
107                              : $_[0] -> bstr() cmp "$_[1]"; },
108
109  # overload key: str_comparison
110
111#  'lt'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrlt($_[0])
112#                              : $_[0] -> bstrlt($_[1]); },
113#
114#  'le'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrle($_[0])
115#                              : $_[0] -> bstrle($_[1]); },
116#
117#  'gt'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrgt($_[0])
118#                              : $_[0] -> bstrgt($_[1]); },
119#
120#  'ge'    =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrge($_[0])
121#                              : $_[0] -> bstrge($_[1]); },
122#
123#  'eq'    =>      sub { $_[0] -> bstreq($_[1]); },
124#
125#  'ne'    =>      sub { $_[0] -> bstrne($_[1]); },
126
127  # overload key: binary
128
129  '&'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> band($_[0])
130                              : $_[0] -> copy() -> band($_[1]); },
131
132  '&='    =>      sub { $_[0] -> band($_[1]); },
133
134  '|'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bior($_[0])
135                              : $_[0] -> copy() -> bior($_[1]); },
136
137  '|='    =>      sub { $_[0] -> bior($_[1]); },
138
139  '^'     =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bxor($_[0])
140                              : $_[0] -> copy() -> bxor($_[1]); },
141
142  '^='    =>      sub { $_[0] -> bxor($_[1]); },
143
144#  '&.'    =>      sub { },
145
146#  '&.='   =>      sub { },
147
148#  '|.'    =>      sub { },
149
150#  '|.='   =>      sub { },
151
152#  '^.'    =>      sub { },
153
154#  '^.='   =>      sub { },
155
156  # overload key: unary
157
158  'neg'   =>      sub { $_[0] -> copy() -> bneg(); },
159
160#  '!'     =>      sub { },
161
162  '~'     =>      sub { $_[0] -> copy() -> bnot(); },
163
164#  '~.'    =>      sub { },
165
166  # overload key: mutators
167
168  '++'    =>      sub { $_[0] -> binc() },
169
170  '--'    =>      sub { $_[0] -> bdec() },
171
172  # overload key: func
173
174  'atan2' =>      sub { $_[2] ? ref($_[0]) -> new($_[1]) -> batan2($_[0])
175                              : $_[0] -> copy() -> batan2($_[1]); },
176
177  'cos'   =>      sub { $_[0] -> copy() -> bcos(); },
178
179  'sin'   =>      sub { $_[0] -> copy() -> bsin(); },
180
181  'exp'   =>      sub { $_[0] -> copy() -> bexp($_[1]); },
182
183  'abs'   =>      sub { $_[0] -> copy() -> babs(); },
184
185  'log'   =>      sub { $_[0] -> copy() -> blog(); },
186
187  'sqrt'  =>      sub { $_[0] -> copy() -> bsqrt(); },
188
189  'int'   =>      sub { $_[0] -> copy() -> bint(); },
190
191  # overload key: conversion
192
193  'bool'  =>      sub { $_[0] -> is_zero() ? '' : 1; },
194
195  '""'    =>      sub { $_[0] -> bstr(); },
196
197  '0+'    =>      sub { $_[0] -> numify(); },
198
199  '='     =>      sub { $_[0] -> copy(); },
200
201  ;
202
203##############################################################################
204# global constants, flags and assorted stuff
205
206# the following are public, but their usage is not recommended. Use the
207# accessor methods instead.
208
209# class constants, use Class->constant_name() to access
210# one of 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'
211$round_mode = 'even';
212$accuracy   = undef;
213$precision  = undef;
214$div_scale  = 40;
215
216$upgrade = undef;
217$downgrade = undef;
218# the package we are using for our private parts, defaults to:
219# Math::BigInt->config('lib')
220my $LIB = 'Math::BigInt::Calc';
221
222# are NaNs ok? (otherwise it dies when encountering an NaN) set w/ config()
223$_trap_nan = 0;
224# the same for infinity
225$_trap_inf = 0;
226
227# constant for easier life
228my $nan = 'NaN';
229
230my $IMPORT = 0; # was import() called yet? used to make require work
231
232# some digits of accuracy for blog(undef, 10); which we use in blog() for speed
233my $LOG_10 =
234 '2.3025850929940456840179914546843642076011014886287729760333279009675726097';
235my $LOG_10_A = length($LOG_10)-1;
236# ditto for log(2)
237my $LOG_2 =
238 '0.6931471805599453094172321214581765680755001343602552541206800094933936220';
239my $LOG_2_A = length($LOG_2)-1;
240my $HALF = '0.5';                       # made into an object if nec.
241
242##############################################################################
243# the old code had $rnd_mode, so we need to support it, too
244
245sub TIESCALAR {
246    my ($class) = @_;
247    bless \$round_mode, $class;
248}
249
250sub FETCH {
251    return $round_mode;
252}
253
254sub STORE {
255    $rnd_mode = $_[0]->round_mode($_[1]);
256}
257
258BEGIN {
259    # when someone sets $rnd_mode, we catch this and check the value to see
260    # whether it is valid or not.
261    $rnd_mode   = 'even';
262    tie $rnd_mode, 'Math::BigFloat';
263
264    # we need both of them in this package:
265    *as_int = \&as_number;
266}
267
268sub DESTROY {
269    # going through AUTOLOAD for every DESTROY is costly, avoid it by empty sub
270}
271
272sub AUTOLOAD {
273    # make fxxx and bxxx both work by selectively mapping fxxx() to MBF::bxxx()
274    my $name = $AUTOLOAD;
275
276    $name =~ s/(.*):://;        # split package
277    my $c = $1 || __PACKAGE__;
278    no strict 'refs';
279    $c->import() if $IMPORT == 0;
280    if (!_method_alias($name)) {
281        if (!defined $name) {
282            # delayed load of Carp and avoid recursion
283            croak("$c: Can't call a method without name");
284        }
285        if (!_method_hand_up($name)) {
286            # delayed load of Carp and avoid recursion
287            croak("Can't call $c\-\>$name, not a valid method");
288        }
289        # try one level up, but subst. bxxx() for fxxx() since MBI only got bxxx()
290        $name =~ s/^f/b/;
291        return &{"Math::BigInt"."::$name"}(@_);
292    }
293    my $bname = $name;
294    $bname =~ s/^f/b/;
295    $c .= "::$name";
296    *{$c} = \&{$bname};
297    &{$c};                      # uses @_
298}
299
300##############################################################################
301
302{
303    # valid method aliases for AUTOLOAD
304    my %methods = map { $_ => 1 }
305      qw / fadd fsub fmul fdiv fround ffround fsqrt fmod fstr fsstr fpow fnorm
306           fint facmp fcmp fzero fnan finf finc fdec ffac fneg
307           fceil ffloor frsft flsft fone flog froot fexp
308         /;
309    # valid methods that can be handed up (for AUTOLOAD)
310    my %hand_ups = map { $_ => 1 }
311      qw / is_nan is_inf is_negative is_positive is_pos is_neg
312           accuracy precision div_scale round_mode fabs fnot
313           objectify upgrade downgrade
314           bone binf bnan bzero
315           bsub
316         /;
317
318    sub _method_alias { exists $methods{$_[0]||''}; }
319    sub _method_hand_up { exists $hand_ups{$_[0]||''}; }
320}
321
322sub isa {
323    my ($self, $class) = @_;
324    return if $class =~ /^Math::BigInt/; # we aren't one of these
325    UNIVERSAL::isa($self, $class);
326}
327
328sub config {
329    # return (later set?) configuration data as hash ref
330    my $class = shift || 'Math::BigFloat';
331
332    # Getter/accessor.
333
334    if (@_ == 1 && ref($_[0]) ne 'HASH') {
335        my $param = shift;
336        return $class if $param eq 'class';
337        return $LIB   if $param eq 'with';
338        return $class->SUPER::config($param);
339    }
340
341    # Setter.
342
343    my $cfg = $class->SUPER::config(@_);
344
345    # now we need only to override the ones that are different from our parent
346    $cfg->{class} = $class;
347    $cfg->{with} = $LIB;
348    $cfg;
349}
350
351###############################################################################
352# Constructor methods
353###############################################################################
354
355sub new {
356    # Create a new Math::BigFloat object from a string or another bigfloat object.
357    # _e: exponent
358    # _m: mantissa
359    # sign  => ("+", "-", "+inf", "-inf", or "NaN")
360
361    my $self    = shift;
362    my $selfref = ref $self;
363    my $class   = $selfref || $self;
364
365    # Make "require" work.
366
367    $class -> import() if $IMPORT == 0;
368
369    # Although this use has been discouraged for more than 10 years, people
370    # apparently still use it, so we still support it.
371
372    return $class -> bzero() unless @_;
373
374    my ($wanted, @r) = @_;
375
376    if (!defined($wanted)) {
377        #if (warnings::enabled("uninitialized")) {
378        #    warnings::warn("uninitialized",
379        #                   "Use of uninitialized value in new()");
380        #}
381        return $class -> bzero(@r);
382    }
383
384    if (!ref($wanted) && $wanted eq "") {
385        #if (warnings::enabled("numeric")) {
386        #    warnings::warn("numeric",
387        #                   q|Argument "" isn't numeric in new()|);
388        #}
389        #return $class -> bzero(@r);
390        return $class -> bnan(@r);
391    }
392
393    # Initialize a new object.
394
395    $self = bless {}, $class unless $selfref;
396
397    # The first following ought to work. However, it causes a 'Deep recursion on
398    # subroutine "Math::BigFloat::as_number"' in some tests. Fixme!
399
400    if (defined(blessed($wanted)) && $wanted -> isa('Math::BigFloat')) {
401    #if (defined(blessed($wanted)) && UNIVERSAL::isa($wanted, 'Math::BigFloat')) {
402        $self -> {sign} = $wanted -> {sign};
403        $self -> {_m}   = $LIB -> _copy($wanted -> {_m});
404        $self -> {_es}  = $wanted -> {_es};
405        $self -> {_e}   = $LIB -> _copy($wanted -> {_e});
406        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
407        return $self;
408    }
409
410    # Shortcut for Math::BigInt and its subclasses. This should be improved.
411
412    if (defined(blessed($wanted))) {
413        if ($wanted -> isa('Math::BigInt')) {
414            $self->{sign} = $wanted -> {sign};
415            $self->{_m}   = $LIB -> _copy($wanted -> {value});
416            $self->{_es}  = '+';
417            $self->{_e}   = $LIB -> _zero();
418            return $self -> bnorm();
419        }
420
421        if ($wanted -> can("as_number")) {
422            $self->{sign} = $wanted -> sign();
423            $self->{_m}   = $wanted -> as_number() -> {value};
424            $self->{_es}  = '+';
425            $self->{_e}   = $LIB -> _zero();
426            return $self -> bnorm();
427        }
428    }
429
430    # Handle Infs.
431
432    if ($wanted =~ /^\s*([+-]?)inf(inity)?\s*\z/i) {
433        return $downgrade->new($wanted) if defined $downgrade;
434        my $sgn = $1 || '+';
435        $self = $class -> binf($sgn);
436        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
437        return $self;
438    }
439
440    # Handle explicit NaNs (not the ones returned due to invalid input).
441
442    if ($wanted =~ /^\s*([+-]?)nan\s*\z/i) {
443        return $downgrade->new($wanted) if defined $downgrade;
444        $self = $class -> bnan();
445        $self->round(@r) unless @r >= 2 && !defined $r[0] && !defined $r[1];
446        return $self;
447    }
448
449    # Shortcut for simple forms like '123' that have no trailing zeros.
450
451    if ($wanted =~ / ^
452                     \s*                        # optional leading whitespace
453                     ( [+-]? )                  # optional sign
454                     0*                         # optional leading zeros
455                     ( [1-9] (?: [0-9]* [1-9] )? )  # significand
456                     \s*                        # optional trailing whitespace
457                     $
458                   /x)
459    {
460        return $downgrade->new($1 . $2) if defined $downgrade;
461        $self->{sign} = $1 || '+';
462        $self->{_m}   = $LIB -> _new($2);
463        $self->{_es}  = '+';
464        $self->{_e}   = $LIB -> _zero();
465        $self->round(@r) unless @r >= 2 && !defined $r[0] && !defined $r[1];
466        return $self;
467    }
468
469    my @parts;
470
471    if (
472        # Handle hexadecimal numbers. We auto-detect hexadecimal numbers if they
473        # have a "0x", "0X", "x", or "X" prefix, cf. CORE::oct().
474
475        $wanted =~ /^\s*[+-]?0?[Xx]/ and
476        @parts = $class -> _hex_str_to_lib_parts($wanted)
477
478          or
479
480        # Handle octal numbers. We auto-detect octal numbers if they have a
481        # "0o", "0O", "o", "O" prefix, cf. CORE::oct().
482
483        $wanted =~ /^\s*[+-]?0?[Oo]/ and
484        @parts = $class -> _oct_str_to_lib_parts($wanted)
485
486          or
487
488        # Handle binary numbers. We auto-detect binary numbers if they have a
489        # "0b", "0B", "b", or "B" prefix, cf. CORE::oct().
490
491        $wanted =~ /^\s*[+-]?0?[Bb]/ and
492        @parts = $class -> _bin_str_to_lib_parts($wanted)
493
494          or
495
496        # At this point, what is left are decimal numbers that aren't handled
497        # above and octal floating point numbers that don't have any of the
498        # "0o", "0O", "o", or "O" prefixes. First see if it is a decimal number.
499
500        @parts = $class -> _dec_str_to_lib_parts($wanted)
501          or
502
503        # See if it is an octal floating point number. The extra check is
504        # included because _oct_str_to_lib_parts() accepts octal numbers that
505        # don't have a prefix (this is needed to make it work with, e.g.,
506        # from_oct() that don't require a prefix). However, Perl requires a
507        # prefix for octal floating point literals. For example, "1p+0" is not
508        # valid, but "01p+0" and "0__1p+0" are.
509
510        $wanted =~ /^\s*[+-]?0_*\d/ and
511        @parts = $class -> _oct_str_to_lib_parts($wanted))
512    {
513        # The value is an integer iff the exponent is non-negative.
514
515        if ($parts[2] eq '+' && $downgrade) {
516            return $downgrade->new($wanted, @r);
517        }
518
519        ($self->{sign}, $self->{_m}, $self->{_es}, $self->{_e}) = @parts;
520        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
521        return $self;
522    }
523
524    # If we get here, the value is neither a valid decimal, binary, octal, or
525    # hexadecimal number. It is not an explicit Inf or a NaN either.
526
527    return $class -> bnan();
528}
529
530sub from_dec {
531    my $self    = shift;
532    my $selfref = ref $self;
533    my $class   = $selfref || $self;
534
535    # Don't modify constant (read-only) objects.
536
537    return if $selfref && $self->modify('from_dec');
538
539    my $str = shift;
540    my @r = @_;
541
542    # If called as a class method, initialize a new object.
543
544    $self = $class -> bzero() unless $selfref;
545
546    if (my @parts = $class -> _dec_str_to_lib_parts($str)) {
547
548        # The value is an integer iff the exponent is non-negative.
549
550        if ($parts[2] eq '+') {
551            return $downgrade->new($str, @r) if defined $downgrade;
552        }
553
554        ($self->{sign}, $self->{_m}, $self->{_es}, $self->{_e}) = @parts;
555        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
556        return $self;
557    }
558
559    return $self -> bnan(@r);
560}
561
562sub from_hex {
563    my $self    = shift;
564    my $selfref = ref $self;
565    my $class   = $selfref || $self;
566
567    # Don't modify constant (read-only) objects.
568
569    return if $selfref && $self->modify('from_hex');
570
571    my $str = shift;
572    my @r = @_;
573
574    # If called as a class method, initialize a new object.
575
576    $self = $class -> bzero() unless $selfref;
577
578    if (my @parts = $class -> _hex_str_to_lib_parts($str)) {
579
580        # The value is an integer iff the exponent is non-negative.
581
582        if ($parts[2] eq '+' && defined $downgrade) {
583            return $downgrade -> from_hex($str, @r);
584        }
585
586        ($self->{sign}, $self->{_m}, $self->{_es}, $self->{_e}) = @parts;
587        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
588        return $self;
589    }
590
591    return $self -> bnan(@r);
592}
593
594sub from_oct {
595    my $self    = shift;
596    my $selfref = ref $self;
597    my $class   = $selfref || $self;
598
599    # Don't modify constant (read-only) objects.
600
601    return if $selfref && $self->modify('from_oct');
602
603    my $str = shift;
604    my @r = @_;
605
606    # If called as a class method, initialize a new object.
607
608    $self = $class -> bzero() unless $selfref;
609
610    if (my @parts = $class -> _oct_str_to_lib_parts($str)) {
611
612        # The value is an integer iff the exponent is non-negative.
613
614        if ($parts[2] eq '+') {
615            return $downgrade -> from_oct($str, @r) if defined $downgrade;
616        }
617
618        ($self->{sign}, $self->{_m}, $self->{_es}, $self->{_e}) = @parts;
619        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
620        return $self;
621    }
622
623    return $self -> bnan(@r);
624}
625
626sub from_bin {
627    my $self    = shift;
628    my $selfref = ref $self;
629    my $class   = $selfref || $self;
630
631    # Don't modify constant (read-only) objects.
632
633    return if $selfref && $self->modify('from_bin');
634
635    my $str = shift;
636    my @r = @_;
637
638    # If called as a class method, initialize a new object.
639
640    $self = $class -> bzero() unless $selfref;
641
642    if (my @parts = $class -> _bin_str_to_lib_parts($str)) {
643
644        # The value is an integer iff the exponent is non-negative.
645
646        if ($parts[2] eq '+') {
647            return $downgrade -> from_bin($str, @r) if defined $downgrade;
648        }
649
650        ($self->{sign}, $self->{_m}, $self->{_es}, $self->{_e}) = @parts;
651        $self->round(@r) unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
652        return $self;
653    }
654
655    return $self -> bnan(@r);
656}
657
658sub from_ieee754 {
659    my $self    = shift;
660    my $selfref = ref $self;
661    my $class   = $selfref || $self;
662
663    # Don't modify constant (read-only) objects.
664
665    return if $selfref && $self->modify('from_ieee754');
666
667    my $in     = shift;     # input string (or raw bytes)
668    my $format = shift;     # format ("binary32", "decimal64" etc.)
669    my $enc;                # significand encoding (applies only to decimal)
670    my $k;                  # storage width in bits
671    my $b;                  # base
672    my @r = @_;
673
674    if ($format =~ /^binary(\d+)\z/) {
675        $k = $1;
676        $b = 2;
677    } elsif ($format =~ /^decimal(\d+)(dpd|bcd)?\z/) {
678        $k = $1;
679        $b = 10;
680        $enc = $2 || 'dpd';     # default is dencely-packed decimals (DPD)
681    } elsif ($format eq 'half') {
682        $k = 16;
683        $b = 2;
684    } elsif ($format eq 'single') {
685        $k = 32;
686        $b = 2;
687    } elsif ($format eq 'double') {
688        $k = 64;
689        $b = 2;
690    } elsif ($format eq 'quadruple') {
691        $k = 128;
692        $b = 2;
693    } elsif ($format eq 'octuple') {
694        $k = 256;
695        $b = 2;
696    } elsif ($format eq 'sexdecuple') {
697        $k = 512;
698        $b = 2;
699    }
700
701    if ($b == 2) {
702
703        # Get the parameters for this format.
704
705        my $p;                      # precision (in bits)
706        my $t;                      # number of bits in significand
707        my $w;                      # number of bits in exponent
708
709        if ($k == 16) {             # binary16 (half-precision)
710            $p = 11;
711            $t = 10;
712            $w =  5;
713        } elsif ($k == 32) {        # binary32 (single-precision)
714            $p = 24;
715            $t = 23;
716            $w =  8;
717        } elsif ($k == 64) {        # binary64 (double-precision)
718            $p = 53;
719            $t = 52;
720            $w = 11;
721        } else {                    # binaryN (quadruple-precision and above)
722            if ($k < 128 || $k != 32 * sprintf('%.0f', $k / 32)) {
723                croak "Number of bits must be 16, 32, 64, or >= 128 and",
724                  " a multiple of 32";
725            }
726            $p = $k - sprintf('%.0f', 4 * log($k) / log(2)) + 13;
727            $t = $p - 1;
728            $w = $k - $t - 1;
729        }
730
731        # The maximum exponent, minimum exponent, and exponent bias.
732
733        my $emax = Math::BigInt -> new(2) -> bpow($w - 1) -> bdec();
734        my $emin = 1 - $emax;
735        my $bias = $emax;
736
737        # Undefined input.
738
739        unless (defined $in) {
740            carp("Input is undefined");
741            return $self -> bzero(@r);
742        }
743
744        # Make sure input string is a string of zeros and ones.
745
746        my $len = CORE::length $in;
747        if (8 * $len == $k) {                   # bytes
748            $in = unpack "B*", $in;
749        } elsif (4 * $len == $k) {              # hexadecimal
750            if ($in =~ /([^\da-f])/i) {
751                croak "Illegal hexadecimal digit '$1'";
752            }
753            $in = unpack "B*", pack "H*", $in;
754        } elsif ($len == $k) {                  # bits
755            if ($in =~ /([^01])/) {
756                croak "Illegal binary digit '$1'";
757            }
758        } else {
759            croak "Unknown input -- $in";
760        }
761
762        # Split bit string into sign, exponent, and mantissa/significand.
763
764        my $sign = substr($in, 0, 1) eq '1' ? '-' : '+';
765        my $expo = $class -> from_bin(substr($in, 1, $w));
766        my $mant = $class -> from_bin(substr($in, $w + 1));
767
768        my $x;
769
770        $expo -> bsub($bias);                   # subtract bias
771
772        if ($expo < $emin) {                    # zero and subnormals
773            if ($mant == 0) {                   # zero
774                $x = $class -> bzero();
775            } else {                            # subnormals
776                # compute (1/$b)**(N) rather than ($b)**(-N)
777                $x = $class -> new("0.5");      # 1/$b
778                $x -> bpow($bias + $t - 1) -> bmul($mant);
779                $x -> bneg() if $sign eq '-';
780            }
781        }
782
783        elsif ($expo > $emax) {                 # inf and nan
784            if ($mant == 0) {                   # inf
785                $x = $class -> binf($sign);
786            } else {                            # nan
787                $x = $class -> bnan();
788            }
789        }
790
791        else {                                  # normals
792            $mant = $class -> new(2) -> bpow($t) -> badd($mant);
793            if ($expo < $t) {
794                # compute (1/$b)**(N) rather than ($b)**(-N)
795                $x = $class -> new("0.5");      # 1/$b
796                $x -> bpow($t - $expo) -> bmul($mant);
797            } else {
798                $x = $class -> new(2);
799                $x -> bpow($expo - $t) -> bmul($mant);
800            }
801            $x -> bneg() if $sign eq '-';
802        }
803
804        if ($selfref) {
805            $self -> {sign} = $x -> {sign};
806            $self -> {_m}   = $x -> {_m};
807            $self -> {_es}  = $x -> {_es};
808            $self -> {_e}   = $x -> {_e};
809        } else {
810            $self = $x;
811        }
812
813        return $downgrade -> new($x, @r)
814          if defined($downgrade) && $x -> is_int();
815        return $self -> round(@r);
816    }
817
818    croak("The format '$format' is not yet supported.");
819}
820
821sub bzero {
822    # create/assign '+0'
823
824    if (@_ == 0) {
825        #carp("Using bone() as a function is deprecated;",
826        #           " use bone() as a method instead");
827        unshift @_, __PACKAGE__;
828    }
829
830    my $self    = shift;
831    my $selfref = ref $self;
832    my $class   = $selfref || $self;
833
834    $self->import() if $IMPORT == 0;            # make require work
835    return if $selfref && $self->modify('bzero');
836
837    return $downgrade->bzero() if defined $downgrade;
838
839    $self = bless {}, $class unless $selfref;
840
841    $self -> {sign} = '+';
842    $self -> {_m}   = $LIB -> _zero();
843    $self -> {_es}  = '+';
844    $self -> {_e}   = $LIB -> _zero();
845
846    # If rounding parameters are given as arguments, use them. If no rounding
847    # parameters are given, and if called as a class method initialize the new
848    # instance with the class variables.
849
850    if (@_) {
851        croak "can't specify both accuracy and precision"
852          if @_ >= 2 && defined $_[0] && defined $_[1];
853        $self->{_a} = $_[0];
854        $self->{_p} = $_[1];
855    } else {
856        unless($selfref) {
857            $self->{_a} = $class -> accuracy();
858            $self->{_p} = $class -> precision();
859        }
860    }
861
862    return $self;
863}
864
865sub bone {
866    # Create or assign '+1' (or -1 if given sign '-').
867
868    if (@_ == 0 || (defined($_[0]) && ($_[0] eq '+' || $_[0] eq '-'))) {
869        #carp("Using bone() as a function is deprecated;",
870        #           " use bone() as a method instead");
871        unshift @_, __PACKAGE__;
872    }
873
874    my $self    = shift;
875    my $selfref = ref $self;
876    my $class   = $selfref || $self;
877
878    $self->import() if $IMPORT == 0;            # make require work
879    return if $selfref && $self->modify('bone');
880
881    return $downgrade->bone() if defined $downgrade;
882
883    my $sign = shift;
884    $sign = defined $sign && $sign =~ /^\s*-/ ? "-" : "+";
885
886    $self = bless {}, $class unless $selfref;
887
888    $self -> {sign} = $sign;
889    $self -> {_m}   = $LIB -> _one();
890    $self -> {_es}  = '+';
891    $self -> {_e}   = $LIB -> _zero();
892
893    # If rounding parameters are given as arguments, use them. If no rounding
894    # parameters are given, and if called as a class method initialize the new
895    # instance with the class variables.
896
897    if (@_) {
898        croak "can't specify both accuracy and precision"
899          if @_ >= 2 && defined $_[0] && defined $_[1];
900        $self->{_a} = $_[0];
901        $self->{_p} = $_[1];
902    } else {
903        unless($selfref) {
904            $self->{_a} = $class -> accuracy();
905            $self->{_p} = $class -> precision();
906        }
907    }
908
909    return $self;
910}
911
912sub binf {
913    # create/assign a '+inf' or '-inf'
914
915    if (@_ == 0 || (defined($_[0]) && !ref($_[0]) &&
916                    $_[0] =~ /^\s*[+-](inf(inity)?)?\s*$/))
917    {
918        #carp("Using binf() as a function is deprecated;",
919        #           " use binf() as a method instead");
920        unshift @_, __PACKAGE__;
921    }
922
923    return $downgrade->binf(@_) if defined $downgrade;
924
925    my $self    = shift;
926    my $selfref = ref $self;
927    my $class   = $selfref || $self;
928
929    {
930        no strict 'refs';
931        if (${"${class}::_trap_inf"}) {
932            croak("Tried to create +-inf in $class->binf()");
933        }
934    }
935
936    $self->import() if $IMPORT == 0;            # make require work
937    return if $selfref && $self->modify('binf');
938
939    my $sign = shift;
940    $sign = defined $sign && $sign =~ /^\s*-/ ? "-" : "+";
941
942    $self = bless {}, $class unless $selfref;
943
944    $self -> {sign} = $sign . 'inf';
945    $self -> {_m}   = $LIB -> _zero();
946    $self -> {_es}  = '+';
947    $self -> {_e}   = $LIB -> _zero();
948
949    # If rounding parameters are given as arguments, use them. If no rounding
950    # parameters are given, and if called as a class method initialize the new
951    # instance with the class variables.
952
953    if (@_) {
954        croak "can't specify both accuracy and precision"
955          if @_ >= 2 && defined $_[0] && defined $_[1];
956        $self->{_a} = $_[0];
957        $self->{_p} = $_[1];
958    } else {
959        unless($selfref) {
960            $self->{_a} = $class -> accuracy();
961            $self->{_p} = $class -> precision();
962        }
963    }
964
965    return $self;
966}
967
968sub bnan {
969    # create/assign a 'NaN'
970
971    if (@_ == 0) {
972        #carp("Using bnan() as a function is deprecated;",
973        #           " use bnan() as a method instead");
974        unshift @_, __PACKAGE__;
975    }
976
977    return $downgrade->bnan(@_) if defined $downgrade;
978
979    my $self    = shift;
980    my $selfref = ref $self;
981    my $class   = $selfref || $self;
982
983    {
984        no strict 'refs';
985        if (${"${class}::_trap_nan"}) {
986            croak("Tried to create NaN in $class->bnan()");
987        }
988    }
989
990    $self->import() if $IMPORT == 0;            # make require work
991    return if $selfref && $self->modify('bnan');
992
993    $self = bless {}, $class unless $selfref;
994
995    $self -> {sign} = $nan;
996    $self -> {_m}   = $LIB -> _zero();
997    $self -> {_es}  = '+';
998    $self -> {_e}   = $LIB -> _zero();
999
1000    # If rounding parameters are given as arguments, use them. If no rounding
1001    # parameters are given, and if called as a class method initialize the new
1002    # instance with the class variables.
1003
1004    if (@_) {
1005        croak "can't specify both accuracy and precision"
1006          if @_ >= 2 && defined $_[0] && defined $_[1];
1007        $self->{_a} = $_[0];
1008        $self->{_p} = $_[1];
1009    } else {
1010        unless($selfref) {
1011            $self->{_a} = $class -> accuracy();
1012            $self->{_p} = $class -> precision();
1013        }
1014    }
1015
1016    return $self;
1017}
1018
1019sub bpi {
1020
1021    # Called as                 Argument list
1022    # ---------                 -------------
1023    # Math::BigFloat->bpi()     ("Math::BigFloat")
1024    # Math::BigFloat->bpi(10)   ("Math::BigFloat", 10)
1025    # $x->bpi()                 ($x)
1026    # $x->bpi(10)               ($x, 10)
1027    # Math::BigFloat::bpi()     ()
1028    # Math::BigFloat::bpi(10)   (10)
1029    #
1030    # In ambiguous cases, we favour the OO-style, so the following case
1031    #
1032    #   $n = Math::BigFloat->new("10");
1033    #   $x = Math::BigFloat->bpi($n);
1034    #
1035    # which gives an argument list with the single element $n, is resolved as
1036    #
1037    #   $n->bpi();
1038
1039    my $self    = shift;
1040    my $selfref = ref $self;
1041    my $class   = $selfref || $self;
1042
1043    my @r;                      # rounding paramters
1044
1045    # If bpi() is called as a function ...
1046    #
1047    # This cludge is necessary because we still support bpi() as a function. If
1048    # bpi() is called with either no argument or one argument, and that one
1049    # argument is either undefined or a scalar that looks like a number, then
1050    # we assume bpi() is called as a function.
1051
1052    if (@_ == 0 &&
1053        (defined($self) && !ref($self) && $self =~ /^\s*[+-]?\d/)
1054          ||
1055        !defined($self))
1056    {
1057        $r[0]  = $self;
1058        $class = __PACKAGE__;
1059        $self  = bless {}, $class;              # initialize
1060    }
1061
1062    # ... or if bpi() is called as a method ...
1063
1064    else {
1065        @r = @_;
1066        if ($selfref) {                     # bpi() called as instance method
1067            return $self if $self -> modify('bpi');
1068        } else {                            # bpi() called as class method
1069            $self  = bless {}, $class;      # initialize
1070        }
1071    }
1072
1073    ($self, @r) = $self -> _find_round_parameters(@r);
1074
1075    # The accuracy, i.e., the number of digits. Pi has one digit before the
1076    # dot, so a precision of 4 digits is equivalent to an accuracy of 5 digits.
1077
1078    my $n = defined $r[0] ? $r[0]
1079          : defined $r[1] ? 1 - $r[1]
1080          : $self -> div_scale();
1081
1082    my $rmode = defined $r[2] ? $r[2] : $self -> round_mode();
1083
1084    my $pi;
1085
1086    if ($n <= 1000) {
1087
1088        # 75 x 14 = 1050 digits
1089
1090        my $all_digits = <<EOF;
1091314159265358979323846264338327950288419716939937510582097494459230781640628
1092620899862803482534211706798214808651328230664709384460955058223172535940812
1093848111745028410270193852110555964462294895493038196442881097566593344612847
1094564823378678316527120190914564856692346034861045432664821339360726024914127
1095372458700660631558817488152092096282925409171536436789259036001133053054882
1096046652138414695194151160943305727036575959195309218611738193261179310511854
1097807446237996274956735188575272489122793818301194912983367336244065664308602
1098139494639522473719070217986094370277053921717629317675238467481846766940513
1099200056812714526356082778577134275778960917363717872146844090122495343014654
1100958537105079227968925892354201995611212902196086403441815981362977477130996
1101051870721134999999837297804995105973173281609631859502445945534690830264252
1102230825334468503526193118817101000313783875288658753320838142061717766914730
1103359825349042875546873115956286388235378759375195778185778053217122680661300
1104192787661119590921642019893809525720106548586327886593615338182796823030195
1105EOF
1106
1107        # Should we round up?
1108
1109        my $round_up;
1110
1111        # From the string above, we need to extract the number of digits we
1112        # want plus extra characters for the newlines.
1113
1114        my $nchrs = $n + int($n / 75);
1115
1116        # Extract the digits we want.
1117
1118        my $digits = substr($all_digits, 0, $nchrs);
1119
1120        # Find out whether we should round up or down. Rounding is easy, since
1121        # pi is trancendental. With directed rounding, it doesn't matter what
1122        # the following digits are. With rounding to nearest, we only have to
1123        # look at one extra digit.
1124
1125        if ($rmode eq 'trunc') {
1126            $round_up = 0;
1127        } else {
1128            my $next_digit = substr($all_digits, $nchrs, 1);
1129            $round_up = $next_digit lt '5' ? 0 : 1;
1130        }
1131
1132        # Remove the newlines.
1133
1134        $digits =~ tr/0-9//cd;
1135
1136        # Now do the rounding. We could easily make the regex substitution
1137        # handle all cases, but we avoid using the regex engine when it is
1138        # simple to avoid it.
1139
1140        if ($round_up) {
1141            my $last_digit = substr($digits, -1, 1);
1142            if ($last_digit lt '9') {
1143                substr($digits, -1, 1) = ++$last_digit;
1144            } else {
1145                $digits =~ s/([0-8])(9+)$/ ($1 + 1) . ("0" x CORE::length($2)) /e;
1146            }
1147        }
1148
1149        # Append the exponent and convert to an object.
1150
1151        $pi = Math::BigFloat -> new($digits . 'e-' . ($n - 1));
1152
1153    } else {
1154
1155        # For large accuracy, the arctan formulas become very inefficient with
1156        # Math::BigFloat, so use Brent-Salamin (aka AGM or Gauss-Legendre).
1157
1158        # Use a few more digits in the intermediate computations.
1159        $n += 8;
1160
1161        $HALF = $class -> new($HALF) unless ref($HALF);
1162        my ($an, $bn, $tn, $pn) = ($class -> bone, $HALF -> copy() -> bsqrt($n),
1163                                   $HALF -> copy() -> bmul($HALF), $class -> bone);
1164        while ($pn < $n) {
1165            my $prev_an = $an -> copy();
1166            $an -> badd($bn) -> bmul($HALF, $n);
1167            $bn -> bmul($prev_an) -> bsqrt($n);
1168            $prev_an -> bsub($an);
1169            $tn -> bsub($pn * $prev_an * $prev_an);
1170            $pn -> badd($pn);
1171        }
1172        $an -> badd($bn);
1173        $an -> bmul($an, $n) -> bdiv(4 * $tn, $n);
1174
1175        $an -> round(@r);
1176        $pi = $an;
1177    }
1178
1179    if (defined $r[0]) {
1180        $pi -> accuracy($r[0]);
1181    } elsif (defined $r[1]) {
1182        $pi -> precision($r[1]);
1183    }
1184
1185    for my $key (qw/ sign _m _es _e _a _p /) {
1186        $self -> {$key} = $pi -> {$key};
1187    }
1188
1189    return $self;
1190}
1191
1192sub copy {
1193    my $self    = shift;
1194    my $selfref = ref $self;
1195    my $class   = $selfref || $self;
1196
1197    # If called as a class method, the object to copy is the next argument.
1198
1199    $self = shift() unless $selfref;
1200
1201    my $copy = bless {}, $class;
1202
1203    $copy->{sign} = $self->{sign};
1204    $copy->{_es}  = $self->{_es};
1205    $copy->{_m}   = $LIB->_copy($self->{_m});
1206    $copy->{_e}   = $LIB->_copy($self->{_e});
1207    $copy->{_a}   = $self->{_a} if exists $self->{_a};
1208    $copy->{_p}   = $self->{_p} if exists $self->{_p};
1209
1210    return $copy;
1211}
1212
1213sub as_number {
1214    # return copy as a bigint representation of this Math::BigFloat number
1215    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
1216
1217    return $x if $x->modify('as_number');
1218
1219    if (!$x->isa('Math::BigFloat')) {
1220        # if the object can as_number(), use it
1221        return $x->as_number() if $x->can('as_number');
1222        # otherwise, get us a float and then a number
1223        $x = $x->can('as_float') ? $x->as_float() : $class->new(0+"$x");
1224    }
1225
1226    return Math::BigInt->binf($x->sign()) if $x->is_inf();
1227    return Math::BigInt->bnan()           if $x->is_nan();
1228
1229    my $z = $LIB->_copy($x->{_m});
1230    if ($x->{_es} eq '-') {                     # < 0
1231        $z = $LIB->_rsft($z, $x->{_e}, 10);
1232    } elsif (! $LIB->_is_zero($x->{_e})) {      # > 0
1233        $z = $LIB->_lsft($z, $x->{_e}, 10);
1234    }
1235    $z = Math::BigInt->new($x->{sign} . $LIB->_str($z));
1236    $z;
1237}
1238
1239###############################################################################
1240# Boolean methods
1241###############################################################################
1242
1243sub is_zero {
1244    # return true if arg (BFLOAT or num_str) is zero
1245    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1246
1247    ($x->{sign} eq '+' && $LIB->_is_zero($x->{_m})) ? 1 : 0;
1248}
1249
1250sub is_one {
1251    # return true if arg (BFLOAT or num_str) is +1 or -1 if signis given
1252    my ($class, $x, $sign) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1253
1254    $sign = '+' if !defined $sign || $sign ne '-';
1255
1256    ($x->{sign} eq $sign &&
1257     $LIB->_is_zero($x->{_e}) &&
1258     $LIB->_is_one($x->{_m})) ? 1 : 0;
1259}
1260
1261sub is_odd {
1262    # return true if arg (BFLOAT or num_str) is odd or false if even
1263    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1264
1265    (($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
1266     ($LIB->_is_zero($x->{_e})) &&
1267     ($LIB->_is_odd($x->{_m}))) ? 1 : 0;
1268}
1269
1270sub is_even {
1271    # return true if arg (BINT or num_str) is even or false if odd
1272    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1273
1274    (($x->{sign} =~ /^[+-]$/) &&        # NaN & +-inf aren't
1275     ($x->{_es} eq '+') &&              # 123.45 isn't
1276     ($LIB->_is_even($x->{_m}))) ? 1 : 0; # but 1200 is
1277}
1278
1279sub is_int {
1280    # return true if arg (BFLOAT or num_str) is an integer
1281    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1282
1283    (($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
1284     ($x->{_es} eq '+')) ? 1 : 0; # 1e-1 => no integer
1285}
1286
1287###############################################################################
1288# Comparison methods
1289###############################################################################
1290
1291sub bcmp {
1292    # Compares 2 values.  Returns one of undef, <0, =0, >0. (suitable for sort)
1293
1294    # set up parameters
1295    my ($class, $x, $y) = (ref($_[0]), @_);
1296
1297    # objectify is costly, so avoid it
1298    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
1299        ($class, $x, $y) = objectify(2, @_);
1300    }
1301
1302    return $upgrade->bcmp($x, $y) if defined $upgrade &&
1303      ((!$x->isa($class)) || (!$y->isa($class)));
1304
1305    # Handle all 'nan' cases.
1306
1307    return    if ($x->{sign} eq $nan) || ($y->{sign} eq $nan);
1308
1309    # Handle all '+inf' and '-inf' cases.
1310
1311    return  0 if ($x->{sign} eq '+inf' && $y->{sign} eq '+inf' ||
1312                  $x->{sign} eq '-inf' && $y->{sign} eq '-inf');
1313    return +1 if $x->{sign} eq '+inf'; # x = +inf and y < +inf
1314    return -1 if $x->{sign} eq '-inf'; # x = -inf and y > -inf
1315    return -1 if $y->{sign} eq '+inf'; # x < +inf and y = +inf
1316    return +1 if $y->{sign} eq '-inf'; # x > -inf and y = -inf
1317
1318    # Handle all cases with opposite signs.
1319
1320    return +1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # also does 0 <=> -y
1321    return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # also does -x <=> 0
1322
1323    # Handle all remaining zero cases.
1324
1325    my $xz = $x->is_zero();
1326    my $yz = $y->is_zero();
1327    return  0 if $xz && $yz;             # 0 <=> 0
1328    return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
1329    return +1 if $yz && $x->{sign} eq '+'; # +x <=> 0
1330
1331    # Both arguments are now finite, non-zero numbers with the same sign.
1332
1333    my $cmp;
1334
1335    # The next step is to compare the exponents, but since each mantissa is an
1336    # integer of arbitrary value, the exponents must be normalized by the length
1337    # of the mantissas before we can compare them.
1338
1339    my $mxl = $LIB->_len($x->{_m});
1340    my $myl = $LIB->_len($y->{_m});
1341
1342    # If the mantissas have the same length, there is no point in normalizing the
1343    # exponents by the length of the mantissas, so treat that as a special case.
1344
1345    if ($mxl == $myl) {
1346
1347        # First handle the two cases where the exponents have different signs.
1348
1349        if ($x->{_es} eq '+' && $y->{_es} eq '-') {
1350            $cmp = +1;
1351        } elsif ($x->{_es} eq '-' && $y->{_es} eq '+') {
1352            $cmp = -1;
1353        }
1354
1355        # Then handle the case where the exponents have the same sign.
1356
1357        else {
1358            $cmp = $LIB->_acmp($x->{_e}, $y->{_e});
1359            $cmp = -$cmp if $x->{_es} eq '-';
1360        }
1361
1362        # Adjust for the sign, which is the same for x and y, and bail out if
1363        # we're done.
1364
1365        $cmp = -$cmp if $x->{sign} eq '-'; # 124 > 123, but -124 < -123
1366        return $cmp if $cmp;
1367
1368    }
1369
1370    # We must normalize each exponent by the length of the corresponding
1371    # mantissa. Life is a lot easier if we first make both exponents
1372    # non-negative. We do this by adding the same positive value to both
1373    # exponent. This is safe, because when comparing the exponents, only the
1374    # relative difference is important.
1375
1376    my $ex;
1377    my $ey;
1378
1379    if ($x->{_es} eq '+') {
1380
1381        # If the exponent of x is >= 0 and the exponent of y is >= 0, there is no
1382        # need to do anything special.
1383
1384        if ($y->{_es} eq '+') {
1385            $ex = $LIB->_copy($x->{_e});
1386            $ey = $LIB->_copy($y->{_e});
1387        }
1388
1389        # If the exponent of x is >= 0 and the exponent of y is < 0, add the
1390        # absolute value of the exponent of y to both.
1391
1392        else {
1393            $ex = $LIB->_copy($x->{_e});
1394            $ex = $LIB->_add($ex, $y->{_e}); # ex + |ey|
1395            $ey = $LIB->_zero();             # -ex + |ey| = 0
1396        }
1397
1398    } else {
1399
1400        # If the exponent of x is < 0 and the exponent of y is >= 0, add the
1401        # absolute value of the exponent of x to both.
1402
1403        if ($y->{_es} eq '+') {
1404            $ex = $LIB->_zero(); # -ex + |ex| = 0
1405            $ey = $LIB->_copy($y->{_e});
1406            $ey = $LIB->_add($ey, $x->{_e}); # ey + |ex|
1407        }
1408
1409        # If the exponent of x is < 0 and the exponent of y is < 0, add the
1410        # absolute values of both exponents to both exponents.
1411
1412        else {
1413            $ex = $LIB->_copy($y->{_e}); # -ex + |ey| + |ex| = |ey|
1414            $ey = $LIB->_copy($x->{_e}); # -ey + |ex| + |ey| = |ex|
1415        }
1416
1417    }
1418
1419    # Now we can normalize the exponents by adding lengths of the mantissas.
1420
1421    $ex = $LIB->_add($ex, $LIB->_new($mxl));
1422    $ey = $LIB->_add($ey, $LIB->_new($myl));
1423
1424    # We're done if the exponents are different.
1425
1426    $cmp = $LIB->_acmp($ex, $ey);
1427    $cmp = -$cmp if $x->{sign} eq '-'; # 124 > 123, but -124 < -123
1428    return $cmp if $cmp;
1429
1430    # Compare the mantissas, but first normalize them by padding the shorter
1431    # mantissa with zeros (shift left) until it has the same length as the longer
1432    # mantissa.
1433
1434    my $mx = $x->{_m};
1435    my $my = $y->{_m};
1436
1437    if ($mxl > $myl) {
1438        $my = $LIB->_lsft($LIB->_copy($my), $LIB->_new($mxl - $myl), 10);
1439    } elsif ($mxl < $myl) {
1440        $mx = $LIB->_lsft($LIB->_copy($mx), $LIB->_new($myl - $mxl), 10);
1441    }
1442
1443    $cmp = $LIB->_acmp($mx, $my);
1444    $cmp = -$cmp if $x->{sign} eq '-'; # 124 > 123, but -124 < -123
1445    return $cmp;
1446
1447}
1448
1449sub bacmp {
1450    # Compares 2 values, ignoring their signs.
1451    # Returns one of undef, <0, =0, >0. (suitable for sort)
1452
1453    # set up parameters
1454    my ($class, $x, $y) = (ref($_[0]), @_);
1455    # objectify is costly, so avoid it
1456    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
1457        ($class, $x, $y) = objectify(2, @_);
1458    }
1459
1460    return $upgrade->bacmp($x, $y) if defined $upgrade &&
1461      ((!$x->isa($class)) || (!$y->isa($class)));
1462
1463    # handle +-inf and NaN's
1464    if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/) {
1465        return    if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1466        return  0 if ($x->is_inf() && $y->is_inf());
1467        return  1 if ($x->is_inf() && !$y->is_inf());
1468        return -1;
1469    }
1470
1471    # shortcut
1472    my $xz = $x->is_zero();
1473    my $yz = $y->is_zero();
1474    return 0 if $xz && $yz;     # 0 <=> 0
1475    return -1 if $xz && !$yz;   # 0 <=> +y
1476    return 1 if $yz && !$xz;    # +x <=> 0
1477
1478    # adjust so that exponents are equal
1479    my $lxm = $LIB->_len($x->{_m});
1480    my $lym = $LIB->_len($y->{_m});
1481    my ($xes, $yes) = (1, 1);
1482    $xes = -1 if $x->{_es} ne '+';
1483    $yes = -1 if $y->{_es} ne '+';
1484    # the numify somewhat limits our length, but makes it much faster
1485    my $lx = $lxm + $xes * $LIB->_num($x->{_e});
1486    my $ly = $lym + $yes * $LIB->_num($y->{_e});
1487    my $l = $lx - $ly;
1488    return $l <=> 0 if $l != 0;
1489
1490    # lengths (corrected by exponent) are equal
1491    # so make mantissa equal-length by padding with zero (shift left)
1492    my $diff = $lxm - $lym;
1493    my $xm = $x->{_m};          # not yet copy it
1494    my $ym = $y->{_m};
1495    if ($diff > 0) {
1496        $ym = $LIB->_copy($y->{_m});
1497        $ym = $LIB->_lsft($ym, $LIB->_new($diff), 10);
1498    } elsif ($diff < 0) {
1499        $xm = $LIB->_copy($x->{_m});
1500        $xm = $LIB->_lsft($xm, $LIB->_new(-$diff), 10);
1501    }
1502    $LIB->_acmp($xm, $ym);
1503}
1504
1505###############################################################################
1506# Arithmetic methods
1507###############################################################################
1508
1509sub bneg {
1510    # (BINT or num_str) return BINT
1511    # negate number or make a negated number from string
1512    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1513
1514    return $x if $x->modify('bneg');
1515
1516    # for +0 do not negate (to have always normalized +0). Does nothing for 'NaN'
1517    $x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $LIB->_is_zero($x->{_m}));
1518
1519    return $downgrade -> new($x)
1520      if defined($downgrade) && ($x -> is_int() || $x -> is_inf() || $x -> is_nan());
1521    return $x;
1522}
1523
1524sub bnorm {
1525    # adjust m and e so that m is smallest possible
1526    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1527
1528    # inf, nan etc
1529    if ($x->{sign} !~ /^[+-]$/) {
1530        return $downgrade->new($x) if defined $downgrade;
1531        return $x;
1532    }
1533
1534    my $zeros = $LIB->_zeros($x->{_m}); # correct for trailing zeros
1535    if ($zeros != 0) {
1536        my $z = $LIB->_new($zeros);
1537        $x->{_m} = $LIB->_rsft($x->{_m}, $z, 10);
1538        if ($x->{_es} eq '-') {
1539            if ($LIB->_acmp($x->{_e}, $z) >= 0) {
1540                $x->{_e} = $LIB->_sub($x->{_e}, $z);
1541                $x->{_es} = '+' if $LIB->_is_zero($x->{_e});
1542            } else {
1543                $x->{_e} = $LIB->_sub($LIB->_copy($z), $x->{_e});
1544                $x->{_es} = '+';
1545            }
1546        } else {
1547            $x->{_e} = $LIB->_add($x->{_e}, $z);
1548        }
1549    } else {
1550        # $x can only be 0Ey if there are no trailing zeros ('0' has 0 trailing
1551        # zeros). So, for something like 0Ey, set y to 1, and -0 => +0
1552        $x->{sign} = '+', $x->{_es} = '+', $x->{_e} = $LIB->_one()
1553          if $LIB->_is_zero($x->{_m});
1554    }
1555
1556    return $downgrade->new($x) if defined($downgrade) && $x->is_int();
1557    $x;
1558}
1559
1560sub binc {
1561    # increment arg by one
1562    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1563
1564    return $x if $x->modify('binc');
1565
1566    if ($x->{_es} eq '-') {
1567        return $x->badd($class->bone(), @r); #  digits after dot
1568    }
1569
1570    if (!$LIB->_is_zero($x->{_e})) # _e == 0 for NaN, inf, -inf
1571    {
1572        # 1e2 => 100, so after the shift below _m has a '0' as last digit
1573        $x->{_m} = $LIB->_lsft($x->{_m}, $x->{_e}, 10); # 1e2 => 100
1574        $x->{_e} = $LIB->_zero();                      # normalize
1575        $x->{_es} = '+';
1576        # we know that the last digit of $x will be '1' or '9', depending on the
1577        # sign
1578    }
1579    # now $x->{_e} == 0
1580    if ($x->{sign} eq '+') {
1581        $x->{_m} = $LIB->_inc($x->{_m});
1582        return $x->bnorm()->bround(@r);
1583    } elsif ($x->{sign} eq '-') {
1584        $x->{_m} = $LIB->_dec($x->{_m});
1585        $x->{sign} = '+' if $LIB->_is_zero($x->{_m}); # -1 +1 => -0 => +0
1586        return $x->bnorm()->bround(@r);
1587    }
1588    # inf, nan handling etc
1589    $x->badd($class->bone(), @r); # badd() does round
1590}
1591
1592sub bdec {
1593    # decrement arg by one
1594    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1595
1596    return $x if $x->modify('bdec');
1597
1598    if ($x->{_es} eq '-') {
1599        return $x->badd($class->bone('-'), @r); #  digits after dot
1600    }
1601
1602    if (!$LIB->_is_zero($x->{_e})) {
1603        $x->{_m} = $LIB->_lsft($x->{_m}, $x->{_e}, 10); # 1e2 => 100
1604        $x->{_e} = $LIB->_zero();                      # normalize
1605        $x->{_es} = '+';
1606    }
1607    # now $x->{_e} == 0
1608    my $zero = $x->is_zero();
1609    # <= 0
1610    if (($x->{sign} eq '-') || $zero) {
1611        $x->{_m} = $LIB->_inc($x->{_m});
1612        $x->{sign} = '-' if $zero;                # 0 => 1 => -1
1613        $x->{sign} = '+' if $LIB->_is_zero($x->{_m}); # -1 +1 => -0 => +0
1614        return $x->bnorm()->round(@r);
1615    }
1616    # > 0
1617    elsif ($x->{sign} eq '+') {
1618        $x->{_m} = $LIB->_dec($x->{_m});
1619        return $x->bnorm()->round(@r);
1620    }
1621    # inf, nan handling etc
1622    $x->badd($class->bone('-'), @r); # does round
1623}
1624
1625sub badd {
1626    # add second arg (BFLOAT or string) to first (BFLOAT) (modifies first)
1627    # return result as BFLOAT
1628
1629    # set up parameters
1630    my ($class, $x, $y, @r) = (ref($_[0]), @_);
1631
1632    # objectify is costly, so avoid it
1633    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
1634        ($class, $x, $y, @r) = objectify(2, @_);
1635    }
1636
1637    return $x if $x->modify('badd');
1638
1639    # inf and NaN handling
1640    if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/) {
1641
1642        # NaN first
1643        if ($x->{sign} eq $nan || $y->{sign} eq $nan) {
1644            $x->bnan();
1645        }
1646
1647        # inf handling
1648        elsif ($x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/) {
1649            # +inf++inf or -inf+-inf => same, rest is NaN
1650            $x->bnan() if $x->{sign} ne $y->{sign};
1651        }
1652
1653        # +-inf + something => +inf; something +-inf => +-inf
1654        elsif ($y->{sign} =~ /^[+-]inf$/) {
1655            $x->{sign} = $y->{sign};
1656        }
1657
1658        return $downgrade->new($x, @r) if defined $downgrade;
1659        return $x;
1660    }
1661
1662    return $upgrade->badd($x, $y, @r) if defined $upgrade &&
1663      ((!$x->isa($class)) || (!$y->isa($class)));
1664
1665    $r[3] = $y;                 # no push!
1666
1667    # for speed: no add for $x + 0
1668    if ($y->is_zero()) {
1669        $x->bround(@r);
1670    }
1671
1672    # for speed: no add for 0 + $y
1673    elsif ($x->is_zero()) {
1674        # make copy, clobbering up x (modify in place!)
1675        $x->{_e} = $LIB->_copy($y->{_e});
1676        $x->{_es} = $y->{_es};
1677        $x->{_m} = $LIB->_copy($y->{_m});
1678        $x->{sign} = $y->{sign} || $nan;
1679        $x->round(@r);
1680    }
1681
1682    else {
1683
1684        # take lower of the two e's and adapt m1 to it to match m2
1685        my $e = $y->{_e};
1686        $e = $LIB->_zero() if !defined $e; # if no BFLOAT?
1687        $e = $LIB->_copy($e);              # make copy (didn't do it yet)
1688
1689        my $es;
1690
1691        ($e, $es) = _e_sub($e, $x->{_e}, $y->{_es} || '+', $x->{_es});
1692        #($e, $es) = $LIB -> _ssub($e, $y->{_es} || '+', $x->{_e}, $x->{_es});
1693
1694        my $add = $LIB->_copy($y->{_m});
1695
1696        if ($es eq '-') {                       # < 0
1697            $x->{_m} = $LIB->_lsft($x->{_m}, $e, 10);
1698            ($x->{_e}, $x->{_es}) = _e_add($x->{_e}, $e, $x->{_es}, $es);
1699            #$x->{_m} = $LIB->_lsft($x->{_m}, $e, 10);
1700            #($x->{_e}, $x->{_es}) = $LIB -> _sadd($x->{_e}, $x->{_es}, $e, $es);
1701        } elsif (!$LIB->_is_zero($e)) {         # > 0
1702            $add = $LIB->_lsft($add, $e, 10);
1703        }
1704
1705        # else: both e are the same, so just leave them
1706
1707        if ($x->{sign} eq $y->{sign}) {
1708            $x->{_m} = $LIB->_add($x->{_m}, $add);
1709        } else {
1710            ($x->{_m}, $x->{sign}) =
1711              _e_add($x->{_m}, $add, $x->{sign}, $y->{sign});
1712            #($x->{_m}, $x->{sign}) =
1713            #  $LIB -> _sadd($x->{_m}, $x->{sign}, $add, $y->{sign});
1714        }
1715
1716        # delete trailing zeros, then round
1717        $x->bnorm()->round(@r);
1718    }
1719
1720    return $downgrade->new($x, @r) if defined($downgrade) && $x -> is_int();
1721    return $x;
1722}
1723
1724sub bsub {
1725    # (BINT or num_str, BINT or num_str) return BINT
1726    # subtract second arg from first, modify first
1727
1728    # set up parameters
1729    my ($class, $x, $y, @r) = (ref($_[0]), @_);
1730
1731    # objectify is costly, so avoid it
1732    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
1733        ($class, $x, $y, @r) = objectify(2, @_);
1734    }
1735
1736    return $x if $x -> modify('bsub');
1737
1738    return $upgrade -> new($x) -> bsub($upgrade -> new($y), @r)
1739      if defined $upgrade && (!$x -> isa($class) || !$y -> isa($class));
1740
1741    if ($y -> is_zero()) {
1742        $x -> round(@r);
1743    } else {
1744
1745        # To correctly handle the special case $x -> bsub($x), we note the sign
1746        # of $x, then flip the sign of $y, and if the sign of $x changed too,
1747        # then we know that $x and $y are the same object.
1748
1749        my $xsign = $x -> {sign};
1750        $y -> {sign} =~ tr/+-/-+/;      # does nothing for NaN
1751        if ($xsign ne $x -> {sign}) {
1752            # special case of $x -> bsub($x) results in 0
1753            if ($xsign =~ /^[+-]$/) {
1754                $x -> bzero(@r);
1755            } else {
1756                $x -> bnan();           # NaN, -inf, +inf
1757            }
1758            return $downgrade->new($x, @r) if defined $downgrade;
1759            return $x;
1760        }
1761        $x = $x -> badd($y, @r);        # badd does not leave internal zeros
1762        $y -> {sign} =~ tr/+-/-+/;      # reset $y (does nothing for NaN)
1763    }
1764    return $downgrade->new($x, @r)
1765      if defined($downgrade) && ($x->is_int() || $x->is_inf() || $x->is_nan());
1766    $x;                         # already rounded by badd() or no rounding
1767}
1768
1769sub bmul {
1770    # multiply two numbers
1771
1772    # set up parameters
1773    my ($class, $x, $y, @r) = (ref($_[0]), @_);
1774    # objectify is costly, so avoid it
1775    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
1776        ($class, $x, $y, @r) = objectify(2, @_);
1777    }
1778
1779    return $x if $x->modify('bmul');
1780
1781    return $x->bnan() if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1782
1783    # inf handling
1784    if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/)) {
1785        return $x->bnan() if $x->is_zero() || $y->is_zero();
1786        # result will always be +-inf:
1787        # +inf * +/+inf => +inf, -inf * -/-inf => +inf
1788        # +inf * -/-inf => -inf, -inf * +/+inf => -inf
1789        return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
1790        return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
1791        return $x->binf('-');
1792    }
1793
1794    return $upgrade->bmul($x, $y, @r) if defined $upgrade &&
1795      ((!$x->isa($class)) || (!$y->isa($class)));
1796
1797    # aEb * cEd = (a*c)E(b+d)
1798    $x->{_m} = $LIB->_mul($x->{_m}, $y->{_m});
1799    ($x->{_e}, $x->{_es}) = _e_add($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
1800    #($x->{_e}, $x->{_es}) = $LIB -> _sadd($x->{_e}, $x->{_es}, $y->{_e}, $y->{_es});
1801
1802    $r[3] = $y;                 # no push!
1803
1804    # adjust sign:
1805    $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
1806    $x->bnorm->round(@r);
1807}
1808
1809sub bmuladd {
1810    # multiply two numbers and add the third to the result
1811
1812    # set up parameters
1813    my ($class, $x, $y, $z, @r) = objectify(3, @_);
1814
1815    return $x if $x->modify('bmuladd');
1816
1817    return $x->bnan() if (($x->{sign} eq $nan) ||
1818                          ($y->{sign} eq $nan) ||
1819                          ($z->{sign} eq $nan));
1820
1821    # inf handling
1822    if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/)) {
1823        return $x->bnan() if $x->is_zero() || $y->is_zero();
1824        # result will always be +-inf:
1825        # +inf * +/+inf => +inf, -inf * -/-inf => +inf
1826        # +inf * -/-inf => -inf, -inf * +/+inf => -inf
1827        return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
1828        return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
1829        return $x->binf('-');
1830    }
1831
1832    return $upgrade->bmul($x, $y, @r) if defined $upgrade &&
1833      ((!$x->isa($class)) || (!$y->isa($class)));
1834
1835    # aEb * cEd = (a*c)E(b+d)
1836    $x->{_m} = $LIB->_mul($x->{_m}, $y->{_m});
1837    ($x->{_e}, $x->{_es}) = _e_add($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
1838    #($x->{_e}, $x->{_es}) = $LIB -> _sadd($x->{_e}, $x->{_es}, $y->{_e}, $y->{_es});
1839
1840    $r[3] = $y;                 # no push!
1841
1842    # adjust sign:
1843    $x->{sign} = $x->{sign} ne $y->{sign} ? '-' : '+';
1844
1845    # z=inf handling (z=NaN handled above)
1846    if ($z->{sign} =~ /^[+-]inf$/) {
1847        $x->{sign} = $z->{sign};
1848        return $downgrade->new($x) if defined $downgrade;
1849        return $x;
1850    }
1851
1852    # take lower of the two e's and adapt m1 to it to match m2
1853    my $e = $z->{_e};
1854    $e = $LIB->_zero() if !defined $e; # if no BFLOAT?
1855    $e = $LIB->_copy($e);              # make copy (didn't do it yet)
1856
1857    my $es;
1858
1859    ($e, $es) = _e_sub($e, $x->{_e}, $z->{_es} || '+', $x->{_es});
1860    #($e, $es) = $LIB -> _ssub($e, $z->{_es} || '+', $x->{_e}, $x->{_es});
1861
1862    my $add = $LIB->_copy($z->{_m});
1863
1864    if ($es eq '-')             # < 0
1865    {
1866        $x->{_m} = $LIB->_lsft($x->{_m}, $e, 10);
1867        ($x->{_e}, $x->{_es}) = _e_add($x->{_e}, $e, $x->{_es}, $es);
1868        #$x->{_m} = $LIB->_lsft($x->{_m}, $e, 10);
1869        #($x->{_e}, $x->{_es}) = $LIB -> _sadd($x->{_e}, $x->{_es}, $e, $es);
1870    } elsif (!$LIB->_is_zero($e)) # > 0
1871    {
1872        $add = $LIB->_lsft($add, $e, 10);
1873    }
1874    # else: both e are the same, so just leave them
1875
1876    if ($x->{sign} eq $z->{sign}) {
1877        # add
1878        $x->{_m} = $LIB->_add($x->{_m}, $add);
1879    } else {
1880        ($x->{_m}, $x->{sign}) =
1881          _e_add($x->{_m}, $add, $x->{sign}, $z->{sign});
1882        #($x->{_m}, $x->{sign}) =
1883        #  $LIB -> _sadd($x->{_m}, $x->{sign}, $add, $z->{sign});
1884    }
1885
1886    # delete trailing zeros, then round
1887    $x->bnorm()->round(@r);
1888}
1889
1890sub bdiv {
1891    # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return
1892    # (BFLOAT, BFLOAT) (quo, rem) or BFLOAT (only quo)
1893
1894    # set up parameters
1895    my ($class, $x, $y, $a, $p, $r) = (ref($_[0]), @_);
1896    # objectify is costly, so avoid it
1897    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
1898        ($class, $x, $y, $a, $p, $r) = objectify(2, @_);
1899    }
1900
1901    return $x if $x->modify('bdiv');
1902
1903    my $wantarray = wantarray;  # call only once
1904
1905    # At least one argument is NaN. This is handled the same way as in
1906    # Math::BigInt -> bdiv().
1907
1908    if ($x -> is_nan() || $y -> is_nan()) {
1909        return $wantarray ? ($x -> bnan(), $class -> bnan()) : $x -> bnan();
1910    }
1911
1912    # Divide by zero and modulo zero. This is handled the same way as in
1913    # Math::BigInt -> bdiv(). See the comment in the code for Math::BigInt ->
1914    # bdiv() for further details.
1915
1916    if ($y -> is_zero()) {
1917        my ($quo, $rem);
1918        if ($wantarray) {
1919            $rem = $x -> copy();
1920        }
1921        if ($x -> is_zero()) {
1922            $quo = $x -> bnan();
1923        } else {
1924            $quo = $x -> binf($x -> {sign});
1925        }
1926        return $wantarray ? ($quo, $rem) : $quo;
1927    }
1928
1929    # Numerator (dividend) is +/-inf. This is handled the same way as in
1930    # Math::BigInt -> bdiv(). See the comment in the code for Math::BigInt ->
1931    # bdiv() for further details.
1932
1933    if ($x -> is_inf()) {
1934        my ($quo, $rem);
1935        $rem = $class -> bnan() if $wantarray;
1936        if ($y -> is_inf()) {
1937            $quo = $x -> bnan();
1938        } else {
1939            my $sign = $x -> bcmp(0) == $y -> bcmp(0) ? '+' : '-';
1940            $quo = $x -> binf($sign);
1941        }
1942        return $wantarray ? ($quo, $rem) : $quo;
1943    }
1944
1945    # Denominator (divisor) is +/-inf. This is handled the same way as in
1946    # Math::BigInt -> bdiv(), with one exception: In scalar context,
1947    # Math::BigFloat does true division (although rounded), not floored division
1948    # (F-division), so a finite number divided by +/-inf is always zero. See the
1949    # comment in the code for Math::BigInt -> bdiv() for further details.
1950
1951    if ($y -> is_inf()) {
1952        my ($quo, $rem);
1953        if ($wantarray) {
1954            if ($x -> is_zero() || $x -> bcmp(0) == $y -> bcmp(0)) {
1955                $rem = $x -> copy();
1956                $quo = $x -> bzero();
1957            } else {
1958                $rem = $class -> binf($y -> {sign});
1959                $quo = $x -> bone('-');
1960            }
1961            return ($quo, $rem);
1962        } else {
1963            if ($y -> is_inf()) {
1964                if ($x -> is_nan() || $x -> is_inf()) {
1965                    return $x -> bnan();
1966                } else {
1967                    return $x -> bzero();
1968                }
1969            }
1970        }
1971    }
1972
1973    # At this point, both the numerator and denominator are finite numbers, and
1974    # the denominator (divisor) is non-zero.
1975
1976    # x == 0?
1977    return wantarray ? ($x, $class->bzero()) : $x if $x->is_zero();
1978
1979    # we need to limit the accuracy to protect against overflow
1980    my $fallback = 0;
1981    my (@params, $scale);
1982    ($x, @params) = $x->_find_round_parameters($a, $p, $r, $y);
1983
1984    return $x if $x->is_nan();  # error in _find_round_parameters?
1985
1986    # no rounding at all, so must use fallback
1987    if (scalar @params == 0) {
1988        # simulate old behaviour
1989        $params[0] = $class->div_scale(); # and round to it as accuracy
1990        $scale = $params[0]+4;            # at least four more for proper round
1991        $params[2] = $r;                  # round mode by caller or undef
1992        $fallback = 1;                    # to clear a/p afterwards
1993    } else {
1994        # the 4 below is empirical, and there might be cases where it is not
1995        # enough...
1996        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
1997    }
1998
1999    my $rem;
2000    $rem = $class -> bzero() if wantarray;
2001
2002    $y = $class->new($y) unless $y->isa('Math::BigFloat');
2003
2004    my $lx = $LIB -> _len($x->{_m}); my $ly = $LIB -> _len($y->{_m});
2005    $scale = $lx if $lx > $scale;
2006    $scale = $ly if $ly > $scale;
2007    my $diff = $ly - $lx;
2008    $scale += $diff if $diff > 0; # if lx << ly, but not if ly << lx!
2009
2010    # check that $y is not 1 nor -1 and cache the result:
2011    my $y_not_one = !($LIB->_is_zero($y->{_e}) && $LIB->_is_one($y->{_m}));
2012
2013    # flipping the sign of $y will also flip the sign of $x for the special
2014    # case of $x->bsub($x); so we can catch it below:
2015    my $xsign = $x->{sign};
2016    $y->{sign} =~ tr/+-/-+/;
2017
2018    if ($xsign ne $x->{sign}) {
2019        # special case of $x /= $x results in 1
2020        $x->bone();             # "fixes" also sign of $y, since $x is $y
2021    } else {
2022        # correct $y's sign again
2023        $y->{sign} =~ tr/+-/-+/;
2024        # continue with normal div code:
2025
2026        # make copy of $x in case of list context for later remainder calculation
2027        if (wantarray && $y_not_one) {
2028            $rem = $x->copy();
2029        }
2030
2031        $x->{sign} = $x->{sign} ne $y->sign() ? '-' : '+';
2032
2033        # check for / +-1 (+/- 1E0)
2034        if ($y_not_one) {
2035            # promote BigInts and it's subclasses (except when already a Math::BigFloat)
2036            $y = $class->new($y) unless $y->isa('Math::BigFloat');
2037
2038            # calculate the result to $scale digits and then round it
2039            # a * 10 ** b / c * 10 ** d => a/c * 10 ** (b-d)
2040            $x->{_m} = $LIB->_lsft($x->{_m}, $LIB->_new($scale), 10);
2041            $x->{_m} = $LIB->_div($x->{_m}, $y->{_m}); # a/c
2042
2043            # correct exponent of $x
2044            ($x->{_e}, $x->{_es}) = _e_sub($x->{_e}, $y->{_e}, $x->{_es}, $y->{_es});
2045            #($x->{_e}, $x->{_es})
2046            #  = $LIB -> _ssub($x->{_e}, $x->{_es}, $y->{_e}, $y->{_es});
2047            # correct for 10**scale
2048            ($x->{_e}, $x->{_es}) = _e_sub($x->{_e}, $LIB->_new($scale), $x->{_es}, '+');
2049            #($x->{_e}, $x->{_es})
2050            #  = $LIB -> _ssub($x->{_e}, $x->{_es}, $LIB->_new($scale), '+');
2051            $x->bnorm();        # remove trailing 0's
2052        }
2053    }                           # end else $x != $y
2054
2055    # shortcut to not run through _find_round_parameters again
2056    if (defined $params[0]) {
2057        delete $x->{_a};               # clear before round
2058        $x->bround($params[0], $params[2]); # then round accordingly
2059    } else {
2060        delete $x->{_p};                # clear before round
2061        $x->bfround($params[1], $params[2]); # then round accordingly
2062    }
2063    if ($fallback) {
2064        # clear a/p after round, since user did not request it
2065        delete $x->{_a}; delete $x->{_p};
2066    }
2067
2068    if (wantarray) {
2069        if ($y_not_one) {
2070            $x -> bfloor();
2071            $rem->bmod($y, @params); # copy already done
2072        }
2073        if ($fallback) {
2074            # clear a/p after round, since user did not request it
2075            delete $rem->{_a}; delete $rem->{_p};
2076        }
2077        $x = $downgrade -> new($x)
2078          if defined($downgrade) && $x -> is_int();
2079        $rem = $downgrade -> new($rem)
2080          if defined($downgrade) && $rem -> is_int();
2081        return ($x, $rem);
2082    }
2083
2084    $x = $downgrade -> new($x) if defined($downgrade) && $x -> is_int();
2085    $x;
2086}
2087
2088sub bmod {
2089    # (dividend: BFLOAT or num_str, divisor: BFLOAT or num_str) return remainder
2090
2091    # set up parameters
2092    my ($class, $x, $y, $a, $p, $r) = (ref($_[0]), @_);
2093    # objectify is costly, so avoid it
2094    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
2095        ($class, $x, $y, $a, $p, $r) = objectify(2, @_);
2096    }
2097
2098    return $x if $x->modify('bmod');
2099
2100    # At least one argument is NaN. This is handled the same way as in
2101    # Math::BigInt -> bmod().
2102
2103    if ($x -> is_nan() || $y -> is_nan()) {
2104        return $x -> bnan();
2105    }
2106
2107    # Modulo zero. This is handled the same way as in Math::BigInt -> bmod().
2108
2109    if ($y -> is_zero()) {
2110        return $x;
2111    }
2112
2113    # Numerator (dividend) is +/-inf. This is handled the same way as in
2114    # Math::BigInt -> bmod().
2115
2116    if ($x -> is_inf()) {
2117        return $x -> bnan();
2118    }
2119
2120    # Denominator (divisor) is +/-inf. This is handled the same way as in
2121    # Math::BigInt -> bmod().
2122
2123    if ($y -> is_inf()) {
2124        if ($x -> is_zero() || $x -> bcmp(0) == $y -> bcmp(0)) {
2125            return $x;
2126        } else {
2127            return $x -> binf($y -> sign());
2128        }
2129    }
2130
2131    return $x->bzero() if $x->is_zero()
2132      || ($x->is_int() &&
2133          # check that $y == +1 or $y == -1:
2134          ($LIB->_is_zero($y->{_e}) && $LIB->_is_one($y->{_m})));
2135
2136    my $cmp = $x->bacmp($y);    # equal or $x < $y?
2137    if ($cmp == 0) {            # $x == $y => result 0
2138        return $x -> bzero($a, $p);
2139    }
2140
2141    # only $y of the operands negative?
2142    my $neg = $x->{sign} ne $y->{sign} ? 1 : 0;
2143
2144    $x->{sign} = $y->{sign};     # calc sign first
2145    if ($cmp < 0 && $neg == 0) { # $x < $y => result $x
2146        return $x -> round($a, $p, $r);
2147    }
2148
2149    my $ym = $LIB->_copy($y->{_m});
2150
2151    # 2e1 => 20
2152    $ym = $LIB->_lsft($ym, $y->{_e}, 10)
2153      if $y->{_es} eq '+' && !$LIB->_is_zero($y->{_e});
2154
2155    # if $y has digits after dot
2156    my $shifty = 0;             # correct _e of $x by this
2157    if ($y->{_es} eq '-')       # has digits after dot
2158    {
2159        # 123 % 2.5 => 1230 % 25 => 5 => 0.5
2160        $shifty = $LIB->_num($y->{_e});  # no more digits after dot
2161        $x->{_m} = $LIB->_lsft($x->{_m}, $y->{_e}, 10); # 123 => 1230, $y->{_m} is already 25
2162    }
2163    # $ym is now mantissa of $y based on exponent 0
2164
2165    my $shiftx = 0;             # correct _e of $x by this
2166    if ($x->{_es} eq '-')       # has digits after dot
2167    {
2168        # 123.4 % 20 => 1234 % 200
2169        $shiftx = $LIB->_num($x->{_e}); # no more digits after dot
2170        $ym = $LIB->_lsft($ym, $x->{_e}, 10); # 123 => 1230
2171    }
2172    # 123e1 % 20 => 1230 % 20
2173    if ($x->{_es} eq '+' && !$LIB->_is_zero($x->{_e})) {
2174        $x->{_m} = $LIB->_lsft($x->{_m}, $x->{_e}, 10); # es => '+' here
2175    }
2176
2177    $x->{_e} = $LIB->_new($shiftx);
2178    $x->{_es} = '+';
2179    $x->{_es} = '-' if $shiftx != 0 || $shifty != 0;
2180    $x->{_e} = $LIB->_add($x->{_e}, $LIB->_new($shifty)) if $shifty != 0;
2181
2182    # now mantissas are equalized, exponent of $x is adjusted, so calc result
2183
2184    $x->{_m} = $LIB->_mod($x->{_m}, $ym);
2185
2186    $x->{sign} = '+' if $LIB->_is_zero($x->{_m}); # fix sign for -0
2187    $x->bnorm();
2188
2189    if ($neg != 0 && ! $x -> is_zero()) # one of them negative => correct in place
2190    {
2191        my $r = $y - $x;
2192        $x->{_m} = $r->{_m};
2193        $x->{_e} = $r->{_e};
2194        $x->{_es} = $r->{_es};
2195        $x->{sign} = '+' if $LIB->_is_zero($x->{_m}); # fix sign for -0
2196        $x->bnorm();
2197    }
2198
2199    $x->round($a, $p, $r, $y);     # round and return
2200}
2201
2202sub bmodpow {
2203    # takes a very large number to a very large exponent in a given very
2204    # large modulus, quickly, thanks to binary exponentiation. Supports
2205    # negative exponents.
2206    my ($class, $num, $exp, $mod) = objectify(3, @_);
2207
2208    return $num if $num->modify('bmodpow');
2209
2210    # check modulus for valid values
2211    return $num->bnan() if ($mod->{sign} ne '+' # NaN, -, -inf, +inf
2212                            || $mod->is_zero());
2213
2214    # check exponent for valid values
2215    if ($exp->{sign} =~ /\w/) {
2216        # i.e., if it's NaN, +inf, or -inf...
2217        return $num->bnan();
2218    }
2219
2220    $num->bmodinv ($mod) if ($exp->{sign} eq '-');
2221
2222    # check num for valid values (also NaN if there was no inverse but $exp < 0)
2223    return $num->bnan() if $num->{sign} !~ /^[+-]$/;
2224
2225    # $mod is positive, sign on $exp is ignored, result also positive
2226
2227    # XXX TODO: speed it up when all three numbers are integers
2228    $num->bpow($exp)->bmod($mod);
2229}
2230
2231sub bpow {
2232    # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
2233    # compute power of two numbers, second arg is used as integer
2234    # modifies first argument
2235
2236    # set up parameters
2237    my ($class, $x, $y, $a, $p, $r) = (ref($_[0]), @_);
2238    # objectify is costly, so avoid it
2239    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
2240        ($class, $x, $y, $a, $p, $r) = objectify(2, @_);
2241    }
2242
2243    return $x if $x -> modify('bpow');
2244
2245    # $x and/or $y is a NaN
2246    return $x -> bnan() if $x -> is_nan() || $y -> is_nan();
2247
2248    # $x and/or $y is a +/-Inf
2249    if ($x -> is_inf("-")) {
2250        return $x -> bzero()   if $y -> is_negative();
2251        return $x -> bnan()    if $y -> is_zero();
2252        return $x            if $y -> is_odd();
2253        return $x -> bneg();
2254    } elsif ($x -> is_inf("+")) {
2255        return $x -> bzero()   if $y -> is_negative();
2256        return $x -> bnan()    if $y -> is_zero();
2257        return $x;
2258    } elsif ($y -> is_inf("-")) {
2259        return $x -> bnan()    if $x -> is_one("-");
2260        return $x -> binf("+") if $x > -1 && $x < 1;
2261        return $x -> bone()    if $x -> is_one("+");
2262        return $x -> bzero();
2263    } elsif ($y -> is_inf("+")) {
2264        return $x -> bnan()    if $x -> is_one("-");
2265        return $x -> bzero()   if $x > -1 && $x < 1;
2266        return $x -> bone()    if $x -> is_one("+");
2267        return $x -> binf("+");
2268    }
2269
2270    if ($x -> is_zero()) {
2271        return $x -> bone() if $y -> is_zero();
2272        return $x -> binf() if $y -> is_negative();
2273        return $x;
2274    }
2275
2276    # We don't support complex numbers, so upgrade or return NaN.
2277
2278    if ($x -> is_negative() && !$y -> is_int()) {
2279        return $upgrade -> bpow($upgrade -> new($x), $y, $a, $p, $r)
2280          if defined $upgrade;
2281        return $x -> bnan();
2282    }
2283
2284    if ($x -> is_one("+") || $y -> is_one()) {
2285        return $x;
2286    }
2287
2288    if ($x -> is_one("-")) {
2289        return $x if $y -> is_odd();
2290        return $x -> bneg();
2291    }
2292
2293    return $x -> _pow($y, $a, $p, $r) if !$y -> is_int();
2294
2295    my $y1 = $y -> as_int()->{value}; # make MBI part
2296
2297    my $new_sign = '+';
2298    $new_sign = $LIB -> _is_odd($y1) ? '-' : '+' if $x->{sign} ne '+';
2299
2300    # calculate $x->{_m} ** $y and $x->{_e} * $y separately (faster)
2301    $x->{_m} = $LIB -> _pow($x->{_m}, $y1);
2302    $x->{_e} = $LIB -> _mul($x->{_e}, $y1);
2303
2304    $x->{sign} = $new_sign;
2305    $x -> bnorm();
2306
2307    # x ** (-y) = 1 / (x ** y)
2308
2309    if ($y->{sign} eq '-') {
2310        # modify $x in place!
2311        my $z = $x -> copy();
2312        $x -> bone();
2313        # round in one go (might ignore y's A!)
2314        return scalar $x -> bdiv($z, $a, $p, $r);
2315    }
2316
2317    $x -> round($a, $p, $r, $y);
2318}
2319
2320sub blog {
2321    # Return the logarithm of the operand. If a second operand is defined, that
2322    # value is used as the base, otherwise the base is assumed to be Euler's
2323    # constant.
2324
2325    my ($class, $x, $base, $a, $p, $r);
2326
2327    # Don't objectify the base, since an undefined base, as in $x->blog() or
2328    # $x->blog(undef) signals that the base is Euler's number.
2329
2330    if (!ref($_[0]) && $_[0] =~ /^[A-Za-z]|::/) {
2331        # E.g., Math::BigFloat->blog(256, 2)
2332        ($class, $x, $base, $a, $p, $r) =
2333          defined $_[2] ? objectify(2, @_) : objectify(1, @_);
2334    } else {
2335        # E.g., Math::BigFloat::blog(256, 2) or $x->blog(2)
2336        ($class, $x, $base, $a, $p, $r) =
2337          defined $_[1] ? objectify(2, @_) : objectify(1, @_);
2338    }
2339
2340    return $x if $x->modify('blog');
2341
2342    return $x -> bnan() if $x -> is_nan();
2343
2344    # we need to limit the accuracy to protect against overflow
2345    my $fallback = 0;
2346    my ($scale, @params);
2347    ($x, @params) = $x->_find_round_parameters($a, $p, $r);
2348
2349    # no rounding at all, so must use fallback
2350    if (scalar @params == 0) {
2351        # simulate old behaviour
2352        $params[0] = $class->div_scale(); # and round to it as accuracy
2353        $params[1] = undef;               # P = undef
2354        $scale = $params[0]+4;            # at least four more for proper round
2355        $params[2] = $r;                  # round mode by caller or undef
2356        $fallback = 1;                    # to clear a/p afterwards
2357    } else {
2358        # the 4 below is empirical, and there might be cases where it is not
2359        # enough...
2360        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2361    }
2362
2363    my $done = 0;
2364    if (defined $base) {
2365        $base = $class -> new($base) unless ref $base;
2366        if ($base -> is_nan() || $base -> is_one()) {
2367            $x -> bnan();
2368            $done = 1;
2369        } elsif ($base -> is_inf() || $base -> is_zero()) {
2370            if ($x -> is_inf() || $x -> is_zero()) {
2371                $x -> bnan();
2372            } else {
2373                $x -> bzero(@params);
2374            }
2375            $done = 1;
2376        } elsif ($base -> is_negative()) { # -inf < base < 0
2377            if ($x -> is_one()) {          #     x = 1
2378                $x -> bzero(@params);
2379            } elsif ($x == $base) {
2380                $x -> bone('+', @params); #     x = base
2381            } else {
2382                $x -> bnan();   #     otherwise
2383            }
2384            $done = 1;
2385        } elsif ($x == $base) {
2386            $x -> bone('+', @params); # 0 < base && 0 < x < inf
2387            $done = 1;
2388        }
2389    }
2390
2391    # We now know that the base is either undefined or positive and finite.
2392
2393    unless ($done) {
2394        if ($x -> is_inf()) {   #   x = +/-inf
2395            my $sign = defined $base && $base < 1 ? '-' : '+';
2396            $x -> binf($sign);
2397            $done = 1;
2398        } elsif ($x -> is_neg()) { #   -inf < x < 0
2399            $x -> bnan();
2400            $done = 1;
2401        } elsif ($x -> is_one()) { #   x = 1
2402            $x -> bzero(@params);
2403            $done = 1;
2404        } elsif ($x -> is_zero()) { #   x = 0
2405            my $sign = defined $base && $base < 1 ? '+' : '-';
2406            $x -> binf($sign);
2407            $done = 1;
2408        }
2409    }
2410
2411    if ($done) {
2412        if ($fallback) {
2413            # clear a/p after round, since user did not request it
2414            delete $x->{_a};
2415            delete $x->{_p};
2416        }
2417        return $x;
2418    }
2419
2420    # when user set globals, they would interfere with our calculation, so
2421    # disable them and later re-enable them
2422    no strict 'refs';
2423    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
2424    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
2425    # we also need to disable any set A or P on $x (_find_round_parameters took
2426    # them already into account), since these would interfere, too
2427    delete $x->{_a}; delete $x->{_p};
2428    # need to disable $upgrade in BigInt, to avoid deep recursion
2429    local $Math::BigInt::upgrade = undef;
2430    local $Math::BigFloat::downgrade = undef;
2431
2432    # upgrade $x if $x is not a Math::BigFloat (handle BigInt input)
2433    # XXX TODO: rebless!
2434    if (!$x->isa('Math::BigFloat')) {
2435        $x = Math::BigFloat->new($x);
2436        $class = ref($x);
2437    }
2438
2439    $done = 0;
2440
2441    # If the base is defined and an integer, try to calculate integer result
2442    # first. This is very fast, and in case the real result was found, we can
2443    # stop right here.
2444    if (defined $base && $base->is_int() && $x->is_int()) {
2445        my $xint = Math::BigInt -> new($x    -> bdstr());
2446        my $bint = Math::BigInt -> new($base -> bdstr());
2447        $xint->blog($bint);
2448
2449        # if we found the exact result, we're done
2450        if ($bint -> bpow($xint) == $x) {
2451            my $xflt = Math::BigFloat -> new($xint -> bdstr());
2452            $x->{sign} = $xflt->{sign};
2453            $x->{_m}   = $xflt->{_m};
2454            $x->{_es}  = $xflt->{_es};
2455            $x->{_e}   = $xflt->{_e};
2456            $done = 1;
2457        }
2458    }
2459
2460    if ($done == 0) {
2461        # First calculate the log to base e (using reduction by 10 and possibly
2462        # also by 2):
2463        $x->_log_10($scale);
2464
2465        # and if a different base was requested, convert it
2466        if (defined $base) {
2467            $base = Math::BigFloat->new($base)
2468              unless $base->isa('Math::BigFloat');
2469            # log_b(x) = ln(x) / ln(b), so compute ln(b)
2470            my $base_log_e = $base->copy()->_log_10($scale);
2471            $x->bdiv($base_log_e, $scale);
2472        }
2473    }
2474
2475    # shortcut to not run through _find_round_parameters again
2476    if (defined $params[0]) {
2477        $x->bround($params[0], $params[2]); # then round accordingly
2478    } else {
2479        $x->bfround($params[1], $params[2]); # then round accordingly
2480    }
2481    if ($fallback) {
2482        # clear a/p after round, since user did not request it
2483        delete $x->{_a};
2484        delete $x->{_p};
2485    }
2486    # restore globals
2487    $$abr = $ab;
2488    $$pbr = $pb;
2489
2490    $x;
2491}
2492
2493sub bexp {
2494    # Calculate e ** X (Euler's number to the power of X)
2495    my ($class, $x, $a, $p, $r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2496
2497    return $x if $x->modify('bexp');
2498
2499    return $x->binf() if $x->{sign} eq '+inf';
2500    return $x->bzero() if $x->{sign} eq '-inf';
2501
2502    # we need to limit the accuracy to protect against overflow
2503    my $fallback = 0;
2504    my ($scale, @params);
2505    ($x, @params) = $x->_find_round_parameters($a, $p, $r);
2506
2507    # also takes care of the "error in _find_round_parameters?" case
2508    return $x if $x->{sign} eq 'NaN';
2509
2510    # no rounding at all, so must use fallback
2511    if (scalar @params == 0) {
2512        # simulate old behaviour
2513        $params[0] = $class->div_scale(); # and round to it as accuracy
2514        $params[1] = undef;               # P = undef
2515        $scale = $params[0]+4;            # at least four more for proper round
2516        $params[2] = $r;                  # round mode by caller or undef
2517        $fallback = 1;                    # to clear a/p afterwards
2518    } else {
2519        # the 4 below is empirical, and there might be cases where it's not
2520        # enough ...
2521        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2522    }
2523
2524    return $x->bone(@params) if $x->is_zero();
2525
2526    if (!$x->isa('Math::BigFloat')) {
2527        $x = Math::BigFloat->new($x);
2528        $class = ref($x);
2529    }
2530
2531    # when user set globals, they would interfere with our calculation, so
2532    # disable them and later re-enable them
2533    no strict 'refs';
2534    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
2535    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
2536    # we also need to disable any set A or P on $x (_find_round_parameters took
2537    # them already into account), since these would interfere, too
2538    delete $x->{_a};
2539    delete $x->{_p};
2540    # need to disable $upgrade in BigInt, to avoid deep recursion
2541    local $Math::BigInt::upgrade = undef;
2542    local $Math::BigFloat::downgrade = undef;
2543
2544    my $x_org = $x->copy();
2545
2546    # We use the following Taylor series:
2547
2548    #           x    x^2   x^3   x^4
2549    #  e = 1 + --- + --- + --- + --- ...
2550    #           1!    2!    3!    4!
2551
2552    # The difference for each term is X and N, which would result in:
2553    # 2 copy, 2 mul, 2 add, 1 inc, 1 div operations per term
2554
2555    # But it is faster to compute exp(1) and then raising it to the
2556    # given power, esp. if $x is really big and an integer because:
2557
2558    #  * The numerator is always 1, making the computation faster
2559    #  * the series converges faster in the case of x == 1
2560    #  * We can also easily check when we have reached our limit: when the
2561    #    term to be added is smaller than "1E$scale", we can stop - f.i.
2562    #    scale == 5, and we have 1/40320, then we stop since 1/40320 < 1E-5.
2563    #  * we can compute the *exact* result by simulating bigrat math:
2564
2565    #  1   1    gcd(3, 4) = 1    1*24 + 1*6    5
2566    #  - + -                  = ---------- =  --
2567    #  6   24                      6*24       24
2568
2569    # We do not compute the gcd() here, but simple do:
2570    #  1   1    1*24 + 1*6   30
2571    #  - + -  = --------- =  --
2572    #  6   24       6*24     144
2573
2574    # In general:
2575    #  a   c    a*d + c*b         and note that c is always 1 and d = (b*f)
2576    #  - + -  = ---------
2577    #  b   d       b*d
2578
2579    # This leads to:         which can be reduced by b to:
2580    #  a   1     a*b*f + b    a*f + 1
2581    #  - + -   = --------- =  -------
2582    #  b   b*f     b*b*f        b*f
2583
2584    # The first terms in the series are:
2585
2586    # 1     1    1    1    1    1     1     1     13700
2587    # -- + -- + -- + -- + -- + --- + --- + ---- = -----
2588    # 1     1    2    6   24   120   720   5040   5040
2589
2590    # Note that we cannot simply reduce 13700/5040 to 685/252, but must keep
2591    # the numerator and the denominator!
2592
2593    if ($scale <= 75) {
2594        # set $x directly from a cached string form
2595        $x->{_m} = $LIB->_new("2718281828459045235360287471352662497757" .
2596                              "2470936999595749669676277240766303535476");
2597        $x->{sign} = '+';
2598        $x->{_es} = '-';
2599        $x->{_e} = $LIB->_new(79);
2600    } else {
2601        # compute A and B so that e = A / B.
2602
2603        # After some terms we end up with this, so we use it as a starting point:
2604        my $A = $LIB->_new("9093339520860578540197197" .
2605                           "0164779391644753259799242");
2606        my $F = $LIB->_new(42);
2607        my $step = 42;
2608
2609        # Compute how many steps we need to take to get $A and $B sufficiently big
2610        my $steps = _len_to_steps($scale - 4);
2611        #    print STDERR "# Doing $steps steps for ", $scale-4, " digits\n";
2612        while ($step++ <= $steps) {
2613            # calculate $a * $f + 1
2614            $A = $LIB->_mul($A, $F);
2615            $A = $LIB->_inc($A);
2616            # increment f
2617            $F = $LIB->_inc($F);
2618        }
2619        # compute $B as factorial of $steps (this is faster than doing it manually)
2620        my $B = $LIB->_fac($LIB->_new($steps));
2621
2622        #  print "A ", $LIB->_str($A), "\nB ", $LIB->_str($B), "\n";
2623
2624        # compute A/B with $scale digits in the result (truncate, not round)
2625        $A = $LIB->_lsft($A, $LIB->_new($scale), 10);
2626        $A = $LIB->_div($A, $B);
2627
2628        $x->{_m} = $A;
2629        $x->{sign} = '+';
2630        $x->{_es} = '-';
2631        $x->{_e} = $LIB->_new($scale);
2632    }
2633
2634    # $x contains now an estimate of e, with some surplus digits, so we can round
2635    if (!$x_org->is_one()) {
2636        # Reduce size of fractional part, followup with integer power of two.
2637        my $lshift = 0;
2638        while ($lshift < 30 && $x_org->bacmp(2 << $lshift) > 0) {
2639            $lshift++;
2640        }
2641        # Raise $x to the wanted power and round it.
2642        if ($lshift == 0) {
2643            $x->bpow($x_org, @params);
2644        } else {
2645            my($mul, $rescale) = (1 << $lshift, $scale+1+$lshift);
2646            $x->bpow(scalar $x_org->bdiv($mul, $rescale), $rescale)->bpow($mul, @params);
2647        }
2648    } else {
2649        # else just round the already computed result
2650        delete $x->{_a};
2651        delete $x->{_p};
2652        # shortcut to not run through _find_round_parameters again
2653        if (defined $params[0]) {
2654            $x->bround($params[0], $params[2]); # then round accordingly
2655        } else {
2656            $x->bfround($params[1], $params[2]); # then round accordingly
2657        }
2658    }
2659    if ($fallback) {
2660        # clear a/p after round, since user did not request it
2661        delete $x->{_a};
2662        delete $x->{_p};
2663    }
2664    # restore globals
2665    $$abr = $ab;
2666    $$pbr = $pb;
2667
2668    $x;                         # return modified $x
2669}
2670
2671sub bnok {
2672    # Calculate n over k (binomial coefficient or "choose" function) as integer.
2673    # set up parameters
2674    my ($class, $x, $y, @r) = (ref($_[0]), @_);
2675
2676    # objectify is costly, so avoid it
2677    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
2678        ($class, $x, $y, @r) = objectify(2, @_);
2679    }
2680
2681    return $x if $x->modify('bnok');
2682
2683    return $x->bnan() if $x->is_nan() || $y->is_nan();
2684    return $x->bnan() if (($x->is_finite() && !$x->is_int()) ||
2685                          ($y->is_finite() && !$y->is_int()));
2686
2687    my $xint = Math::BigInt -> new($x -> bsstr());
2688    my $yint = Math::BigInt -> new($y -> bsstr());
2689    $xint -> bnok($yint);
2690    my $xflt = Math::BigFloat -> new($xint);
2691
2692    $x->{_m}   = $xflt->{_m};
2693    $x->{_e}   = $xflt->{_e};
2694    $x->{_es}  = $xflt->{_es};
2695    $x->{sign} = $xflt->{sign};
2696
2697    return $x;
2698}
2699
2700sub bsin {
2701    # Calculate a sinus of x.
2702    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2703
2704    # taylor:      x^3   x^5   x^7   x^9
2705    #    sin = x - --- + --- - --- + --- ...
2706    #               3!    5!    7!    9!
2707
2708    # we need to limit the accuracy to protect against overflow
2709    my $fallback = 0;
2710    my ($scale, @params);
2711    ($x, @params) = $x->_find_round_parameters(@r);
2712
2713    #         constant object       or error in _find_round_parameters?
2714    return $x if $x->modify('bsin') || $x->is_nan();
2715    return $x->bnan()    if $x->is_inf();
2716    return $x->bzero(@r) if $x->is_zero();
2717
2718    # no rounding at all, so must use fallback
2719    if (scalar @params == 0) {
2720        # simulate old behaviour
2721        $params[0] = $class->div_scale(); # and round to it as accuracy
2722        $params[1] = undef;               # disable P
2723        $scale = $params[0]+4;            # at least four more for proper round
2724        $params[2] = $r[2];               # round mode by caller or undef
2725        $fallback = 1;                    # to clear a/p afterwards
2726    } else {
2727        # the 4 below is empirical, and there might be cases where it is not
2728        # enough...
2729        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2730    }
2731
2732    # when user set globals, they would interfere with our calculation, so
2733    # disable them and later re-enable them
2734    no strict 'refs';
2735    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
2736    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
2737    # we also need to disable any set A or P on $x (_find_round_parameters took
2738    # them already into account), since these would interfere, too
2739    delete $x->{_a};
2740    delete $x->{_p};
2741    # need to disable $upgrade in BigInt, to avoid deep recursion
2742    local $Math::BigInt::upgrade = undef;
2743
2744    my $over = $x * $x;         # X ^ 2
2745    my $x2 = $over->copy();     # X ^ 2; difference between terms
2746    $over->bmul($x);            # X ^ 3 as starting value
2747    my $sign = 1;               # start with -=
2748    my $below = $class->new(6); my $factorial = $class->new(4);
2749    delete $x->{_a};
2750    delete $x->{_p};
2751
2752    my $limit = $class->new("1E-". ($scale-1));
2753    #my $steps = 0;
2754    while (3 < 5) {
2755        # we calculate the next term, and add it to the last
2756        # when the next term is below our limit, it won't affect the outcome
2757        # anymore, so we stop:
2758        my $next = $over->copy()->bdiv($below, $scale);
2759        last if $next->bacmp($limit) <= 0;
2760
2761        if ($sign == 0) {
2762            $x->badd($next);
2763        } else {
2764            $x->bsub($next);
2765        }
2766        $sign = 1-$sign;        # alternate
2767        # calculate things for the next term
2768        $over->bmul($x2);                         # $x*$x
2769        $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2770        $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2771    }
2772
2773    # shortcut to not run through _find_round_parameters again
2774    if (defined $params[0]) {
2775        $x->bround($params[0], $params[2]); # then round accordingly
2776    } else {
2777        $x->bfround($params[1], $params[2]); # then round accordingly
2778    }
2779    if ($fallback) {
2780        # clear a/p after round, since user did not request it
2781        delete $x->{_a};
2782        delete $x->{_p};
2783    }
2784    # restore globals
2785    $$abr = $ab;
2786    $$pbr = $pb;
2787    $x;
2788}
2789
2790sub bcos {
2791    # Calculate a cosinus of x.
2792    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2793
2794    # Taylor:      x^2   x^4   x^6   x^8
2795    #    cos = 1 - --- + --- - --- + --- ...
2796    #               2!    4!    6!    8!
2797
2798    # we need to limit the accuracy to protect against overflow
2799    my $fallback = 0;
2800    my ($scale, @params);
2801    ($x, @params) = $x->_find_round_parameters(@r);
2802
2803    #         constant object       or error in _find_round_parameters?
2804    return $x if $x->modify('bcos') || $x->is_nan();
2805    return $x->bnan()   if $x->is_inf();
2806    return $x->bone(@r) if $x->is_zero();
2807
2808    # no rounding at all, so must use fallback
2809    if (scalar @params == 0) {
2810        # simulate old behaviour
2811        $params[0] = $class->div_scale(); # and round to it as accuracy
2812        $params[1] = undef;               # disable P
2813        $scale = $params[0]+4;            # at least four more for proper round
2814        $params[2] = $r[2];               # round mode by caller or undef
2815        $fallback = 1;                    # to clear a/p afterwards
2816    } else {
2817        # the 4 below is empirical, and there might be cases where it is not
2818        # enough...
2819        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2820    }
2821
2822    # when user set globals, they would interfere with our calculation, so
2823    # disable them and later re-enable them
2824    no strict 'refs';
2825    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
2826    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
2827    # we also need to disable any set A or P on $x (_find_round_parameters took
2828    # them already into account), since these would interfere, too
2829    delete $x->{_a}; delete $x->{_p};
2830    # need to disable $upgrade in BigInt, to avoid deep recursion
2831    local $Math::BigInt::upgrade = undef;
2832
2833    my $over = $x * $x;         # X ^ 2
2834    my $x2 = $over->copy();     # X ^ 2; difference between terms
2835    my $sign = 1;               # start with -=
2836    my $below = $class->new(2);
2837    my $factorial = $class->new(3);
2838    $x->bone();
2839    delete $x->{_a};
2840    delete $x->{_p};
2841
2842    my $limit = $class->new("1E-". ($scale-1));
2843    #my $steps = 0;
2844    while (3 < 5) {
2845        # we calculate the next term, and add it to the last
2846        # when the next term is below our limit, it won't affect the outcome
2847        # anymore, so we stop:
2848        my $next = $over->copy()->bdiv($below, $scale);
2849        last if $next->bacmp($limit) <= 0;
2850
2851        if ($sign == 0) {
2852            $x->badd($next);
2853        } else {
2854            $x->bsub($next);
2855        }
2856        $sign = 1-$sign;        # alternate
2857        # calculate things for the next term
2858        $over->bmul($x2);                         # $x*$x
2859        $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2860        $below->bmul($factorial); $factorial->binc(); # n*(n+1)
2861    }
2862
2863    # shortcut to not run through _find_round_parameters again
2864    if (defined $params[0]) {
2865        $x->bround($params[0], $params[2]); # then round accordingly
2866    } else {
2867        $x->bfround($params[1], $params[2]); # then round accordingly
2868    }
2869    if ($fallback) {
2870        # clear a/p after round, since user did not request it
2871        delete $x->{_a};
2872        delete $x->{_p};
2873    }
2874    # restore globals
2875    $$abr = $ab;
2876    $$pbr = $pb;
2877    $x;
2878}
2879
2880sub batan {
2881    # Calculate a arcus tangens of x.
2882
2883    my $self    = shift;
2884    my $selfref = ref $self;
2885    my $class   = $selfref || $self;
2886
2887    my (@r) = @_;
2888
2889    # taylor:       x^3   x^5   x^7   x^9
2890    #    atan = x - --- + --- - --- + --- ...
2891    #                3     5     7     9
2892
2893    # We need to limit the accuracy to protect against overflow.
2894
2895    my $fallback = 0;
2896    my ($scale, @params);
2897    ($self, @params) = $self->_find_round_parameters(@r);
2898
2899    # Constant object or error in _find_round_parameters?
2900
2901    return $self if $self->modify('batan') || $self->is_nan();
2902
2903    if ($self->{sign} =~ /^[+-]inf\z/) {
2904        # +inf result is PI/2
2905        # -inf result is -PI/2
2906        # calculate PI/2
2907        my $pi = $class->bpi(@r);
2908        # modify $self in place
2909        $self->{_m} = $pi->{_m};
2910        $self->{_e} = $pi->{_e};
2911        $self->{_es} = $pi->{_es};
2912        # -y => -PI/2, +y => PI/2
2913        $self->{sign} = substr($self->{sign}, 0, 1); # "+inf" => "+"
2914        $self -> {_m} = $LIB->_div($self->{_m}, $LIB->_new(2));
2915        return $self;
2916    }
2917
2918    return $self->bzero(@r) if $self->is_zero();
2919
2920    # no rounding at all, so must use fallback
2921    if (scalar @params == 0) {
2922        # simulate old behaviour
2923        $params[0] = $class->div_scale(); # and round to it as accuracy
2924        $params[1] = undef;               # disable P
2925        $scale = $params[0]+4;            # at least four more for proper round
2926        $params[2] = $r[2];               # round mode by caller or undef
2927        $fallback = 1;                    # to clear a/p afterwards
2928    } else {
2929        # the 4 below is empirical, and there might be cases where it is not
2930        # enough...
2931        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
2932    }
2933
2934    # 1 or -1 => PI/4
2935    # inlined is_one() && is_one('-')
2936    if ($LIB->_is_one($self->{_m}) && $LIB->_is_zero($self->{_e})) {
2937        my $pi = $class->bpi($scale - 3);
2938        # modify $self in place
2939        $self->{_m} = $pi->{_m};
2940        $self->{_e} = $pi->{_e};
2941        $self->{_es} = $pi->{_es};
2942        # leave the sign of $self alone (+1 => +PI/4, -1 => -PI/4)
2943        $self->{_m} = $LIB->_div($self->{_m}, $LIB->_new(4));
2944        return $self;
2945    }
2946
2947    # This series is only valid if -1 < x < 1, so for other x we need to
2948    # calculate PI/2 - atan(1/x):
2949    my $pi = undef;
2950    if ($self->bacmp($self->copy()->bone) >= 0) {
2951        # calculate PI/2
2952        $pi = $class->bpi($scale - 3);
2953        $pi->{_m} = $LIB->_div($pi->{_m}, $LIB->_new(2));
2954        # calculate 1/$self:
2955        my $self_copy = $self->copy();
2956        # modify $self in place
2957        $self->bone();
2958        $self->bdiv($self_copy, $scale);
2959    }
2960
2961    my $fmul = 1;
2962    foreach (0 .. int($scale / 20)) {
2963        $fmul *= 2;
2964        $self->bdiv($self->copy()->bmul($self)->binc->bsqrt($scale + 4)->binc, $scale + 4);
2965    }
2966
2967    # When user set globals, they would interfere with our calculation, so
2968    # disable them and later re-enable them.
2969    no strict 'refs';
2970    my $abr = "$class\::accuracy";  my $ab = $$abr; $$abr = undef;
2971    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
2972    # We also need to disable any set A or P on $self (_find_round_parameters
2973    # took them already into account), since these would interfere, too
2974    delete $self->{_a};
2975    delete $self->{_p};
2976    # Need to disable $upgrade in BigInt, to avoid deep recursion.
2977    local $Math::BigInt::upgrade = undef;
2978
2979    my $over = $self * $self;   # X ^ 2
2980    my $self2 = $over->copy();  # X ^ 2; difference between terms
2981    $over->bmul($self);         # X ^ 3 as starting value
2982    my $sign = 1;               # start with -=
2983    my $below = $class->new(3);
2984    my $two = $class->new(2);
2985    delete $self->{_a};
2986    delete $self->{_p};
2987
2988    my $limit = $class->new("1E-". ($scale-1));
2989    #my $steps = 0;
2990    while (1) {
2991        # We calculate the next term, and add it to the last. When the next
2992        # term is below our limit, it won't affect the outcome anymore, so we
2993        # stop:
2994        my $next = $over->copy()->bdiv($below, $scale);
2995        last if $next->bacmp($limit) <= 0;
2996
2997        if ($sign == 0) {
2998            $self->badd($next);
2999        } else {
3000            $self->bsub($next);
3001        }
3002        $sign = 1-$sign;        # alternatex
3003        # calculate things for the next term
3004        $over->bmul($self2);    # $self*$self
3005        $below->badd($two);     # n += 2
3006    }
3007    $self->bmul($fmul);
3008
3009    if (defined $pi) {
3010        my $self_copy = $self->copy();
3011        # modify $self in place
3012        $self->{_m} = $pi->{_m};
3013        $self->{_e} = $pi->{_e};
3014        $self->{_es} = $pi->{_es};
3015        # PI/2 - $self
3016        $self->bsub($self_copy);
3017    }
3018
3019    # Shortcut to not run through _find_round_parameters again.
3020    if (defined $params[0]) {
3021        $self->bround($params[0], $params[2]); # then round accordingly
3022    } else {
3023        $self->bfround($params[1], $params[2]); # then round accordingly
3024    }
3025    if ($fallback) {
3026        # Clear a/p after round, since user did not request it.
3027        delete $self->{_a};
3028        delete $self->{_p};
3029    }
3030
3031    # restore globals
3032    $$abr = $ab;
3033    $$pbr = $pb;
3034    $self;
3035}
3036
3037sub batan2 {
3038    # $y -> batan2($x) returns the arcus tangens of $y / $x.
3039
3040    # Set up parameters.
3041    my ($class, $y, $x, @r) = (ref($_[0]), @_);
3042
3043    # Objectify is costly, so avoid it if we can.
3044    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
3045        ($class, $y, $x, @r) = objectify(2, @_);
3046    }
3047
3048    # Quick exit if $y is read-only.
3049    return $y if $y -> modify('batan2');
3050
3051    # Handle all NaN cases.
3052    return $y -> bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
3053
3054    # We need to limit the accuracy to protect against overflow.
3055    my $fallback = 0;
3056    my ($scale, @params);
3057    ($y, @params) = $y -> _find_round_parameters(@r);
3058
3059    # Error in _find_round_parameters?
3060    return $y if $y->is_nan();
3061
3062    # No rounding at all, so must use fallback.
3063    if (scalar @params == 0) {
3064        # Simulate old behaviour
3065        $params[0] = $class -> div_scale(); # and round to it as accuracy
3066        $params[1] = undef;                 # disable P
3067        $scale = $params[0] + 4; # at least four more for proper round
3068        $params[2] = $r[2];      # round mode by caller or undef
3069        $fallback = 1;           # to clear a/p afterwards
3070    } else {
3071        # The 4 below is empirical, and there might be cases where it is not
3072        # enough ...
3073        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
3074    }
3075
3076    if ($x -> is_inf("+")) {                    # x = inf
3077        if ($y -> is_inf("+")) {                #    y = inf
3078            $y -> bpi($scale) -> bmul("0.25");  #       pi/4
3079        } elsif ($y -> is_inf("-")) {           #    y = -inf
3080            $y -> bpi($scale) -> bmul("-0.25"); #       -pi/4
3081        } else {                                #    -inf < y < inf
3082            return $y -> bzero(@r);             #       0
3083        }
3084    } elsif ($x -> is_inf("-")) {               # x = -inf
3085        if ($y -> is_inf("+")) {                #    y = inf
3086            $y -> bpi($scale) -> bmul("0.75");  #       3/4 pi
3087        } elsif ($y -> is_inf("-")) {           #    y = -inf
3088            $y -> bpi($scale) -> bmul("-0.75"); #       -3/4 pi
3089        } elsif ($y >= 0) {                     #    y >= 0
3090            $y -> bpi($scale);                  #       pi
3091        } else {                                #    y < 0
3092            $y -> bpi($scale) -> bneg();        #       -pi
3093        }
3094    } elsif ($x > 0) {                               # 0 < x < inf
3095        if ($y -> is_inf("+")) {                     #    y = inf
3096            $y -> bpi($scale) -> bmul("0.5");        #       pi/2
3097        } elsif ($y -> is_inf("-")) {                #    y = -inf
3098            $y -> bpi($scale) -> bmul("-0.5");       #       -pi/2
3099        } else {                                     #   -inf < y < inf
3100            $y -> bdiv($x, $scale) -> batan($scale); #       atan(y/x)
3101        }
3102    } elsif ($x < 0) {                        # -inf < x < 0
3103        my $pi = $class -> bpi($scale);
3104        if ($y >= 0) {                        #    y >= 0
3105            $y -> bdiv($x, $scale) -> batan() #       atan(y/x) + pi
3106               -> badd($pi);
3107        } else {                              #    y < 0
3108            $y -> bdiv($x, $scale) -> batan() #       atan(y/x) - pi
3109               -> bsub($pi);
3110        }
3111    } else {                                   # x = 0
3112        if ($y > 0) {                          #    y > 0
3113            $y -> bpi($scale) -> bmul("0.5");  #       pi/2
3114        } elsif ($y < 0) {                     #    y < 0
3115            $y -> bpi($scale) -> bmul("-0.5"); #       -pi/2
3116        } else {                               #    y = 0
3117            return $y -> bzero(@r);            #       0
3118        }
3119    }
3120
3121    $y -> round(@r);
3122
3123    if ($fallback) {
3124        delete $y->{_a};
3125        delete $y->{_p};
3126    }
3127
3128    return $y;
3129}
3130##############################################################################
3131
3132sub bsqrt {
3133    # calculate square root
3134    my ($class, $x, $a, $p, $r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3135
3136    return $x if $x->modify('bsqrt');
3137
3138    return $x->bnan() if $x->{sign} !~ /^\+/;  # NaN, -inf or < 0
3139    return $x if $x->{sign} eq '+inf';         # sqrt(inf) == inf
3140    return $x->round($a, $p, $r) if $x->is_zero() || $x->is_one();
3141
3142    # we need to limit the accuracy to protect against overflow
3143    my $fallback = 0;
3144    my (@params, $scale);
3145    ($x, @params) = $x->_find_round_parameters($a, $p, $r);
3146
3147    return $x if $x->is_nan();  # error in _find_round_parameters?
3148
3149    # no rounding at all, so must use fallback
3150    if (scalar @params == 0) {
3151        # simulate old behaviour
3152        $params[0] = $class->div_scale(); # and round to it as accuracy
3153        $scale = $params[0]+4;            # at least four more for proper round
3154        $params[2] = $r;                  # round mode by caller or undef
3155        $fallback = 1;                    # to clear a/p afterwards
3156    } else {
3157        # the 4 below is empirical, and there might be cases where it is not
3158        # enough...
3159        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
3160    }
3161
3162    # when user set globals, they would interfere with our calculation, so
3163    # disable them and later re-enable them
3164    no strict 'refs';
3165    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
3166    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
3167    # we also need to disable any set A or P on $x (_find_round_parameters took
3168    # them already into account), since these would interfere, too
3169    delete $x->{_a};
3170    delete $x->{_p};
3171    # need to disable $upgrade in BigInt, to avoid deep recursion
3172    local $Math::BigInt::upgrade = undef; # should be really parent class vs MBI
3173
3174    my $i = $LIB->_copy($x->{_m});
3175    $i = $LIB->_lsft($i, $x->{_e}, 10) unless $LIB->_is_zero($x->{_e});
3176    my $xas = Math::BigInt->bzero();
3177    $xas->{value} = $i;
3178
3179    my $gs = $xas->copy()->bsqrt(); # some guess
3180
3181    if (($x->{_es} ne '-')           # guess can't be accurate if there are
3182        # digits after the dot
3183        && ($xas->bacmp($gs * $gs) == 0)) # guess hit the nail on the head?
3184    {
3185        # exact result, copy result over to keep $x
3186        $x->{_m} = $gs->{value};
3187        $x->{_e} = $LIB->_zero();
3188        $x->{_es} = '+';
3189        $x->bnorm();
3190        # shortcut to not run through _find_round_parameters again
3191        if (defined $params[0]) {
3192            $x->bround($params[0], $params[2]); # then round accordingly
3193        } else {
3194            $x->bfround($params[1], $params[2]); # then round accordingly
3195        }
3196        if ($fallback) {
3197            # clear a/p after round, since user did not request it
3198            delete $x->{_a};
3199            delete $x->{_p};
3200        }
3201        # re-enable A and P, upgrade is taken care of by "local"
3202        ${"$class\::accuracy"} = $ab;
3203        ${"$class\::precision"} = $pb;
3204        return $x;
3205    }
3206
3207    # sqrt(2) = 1.4 because sqrt(2*100) = 1.4*10; so we can increase the accuracy
3208    # of the result by multiplying the input by 100 and then divide the integer
3209    # result of sqrt(input) by 10. Rounding afterwards returns the real result.
3210
3211    # The following steps will transform 123.456 (in $x) into 123456 (in $y1)
3212    my $y1 = $LIB->_copy($x->{_m});
3213
3214    my $length = $LIB->_len($y1);
3215
3216    # Now calculate how many digits the result of sqrt(y1) would have
3217    my $digits = int($length / 2);
3218
3219    # But we need at least $scale digits, so calculate how many are missing
3220    my $shift = $scale - $digits;
3221
3222    # This happens if the input had enough digits
3223    # (we take care of integer guesses above)
3224    $shift = 0 if $shift < 0;
3225
3226    # Multiply in steps of 100, by shifting left two times the "missing" digits
3227    my $s2 = $shift * 2;
3228
3229    # We now make sure that $y1 has the same odd or even number of digits than
3230    # $x had. So when _e of $x is odd, we must shift $y1 by one digit left,
3231    # because we always must multiply by steps of 100 (sqrt(100) is 10) and not
3232    # steps of 10. The length of $x does not count, since an even or odd number
3233    # of digits before the dot is not changed by adding an even number of digits
3234    # after the dot (the result is still odd or even digits long).
3235    $s2++ if $LIB->_is_odd($x->{_e});
3236
3237    $y1 = $LIB->_lsft($y1, $LIB->_new($s2), 10);
3238
3239    # now take the square root and truncate to integer
3240    $y1 = $LIB->_sqrt($y1);
3241
3242    # By "shifting" $y1 right (by creating a negative _e) we calculate the final
3243    # result, which is than later rounded to the desired scale.
3244
3245    # calculate how many zeros $x had after the '.' (or before it, depending
3246    # on sign of $dat, the result should have half as many:
3247    my $dat = $LIB->_num($x->{_e});
3248    $dat = -$dat if $x->{_es} eq '-';
3249    $dat += $length;
3250
3251    if ($dat > 0) {
3252        # no zeros after the dot (e.g. 1.23, 0.49 etc)
3253        # preserve half as many digits before the dot than the input had
3254        # (but round this "up")
3255        $dat = int(($dat+1)/2);
3256    } else {
3257        $dat = int(($dat)/2);
3258    }
3259    $dat -= $LIB->_len($y1);
3260    if ($dat < 0) {
3261        $dat = abs($dat);
3262        $x->{_e} = $LIB->_new($dat);
3263        $x->{_es} = '-';
3264    } else {
3265        $x->{_e} = $LIB->_new($dat);
3266        $x->{_es} = '+';
3267    }
3268    $x->{_m} = $y1;
3269    $x->bnorm();
3270
3271    # shortcut to not run through _find_round_parameters again
3272    if (defined $params[0]) {
3273        $x->bround($params[0], $params[2]); # then round accordingly
3274    } else {
3275        $x->bfround($params[1], $params[2]); # then round accordingly
3276    }
3277    if ($fallback) {
3278        # clear a/p after round, since user did not request it
3279        delete $x->{_a};
3280        delete $x->{_p};
3281    }
3282    # restore globals
3283    $$abr = $ab;
3284    $$pbr = $pb;
3285    $x;
3286}
3287
3288sub broot {
3289    # calculate $y'th root of $x
3290
3291    # set up parameters
3292    my ($class, $x, $y, $a, $p, $r) = (ref($_[0]), @_);
3293    # objectify is costly, so avoid it
3294    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
3295        ($class, $x, $y, $a, $p, $r) = objectify(2, @_);
3296    }
3297
3298    return $x if $x->modify('broot');
3299
3300    # NaN handling: $x ** 1/0, x or y NaN, or y inf/-inf or y == 0
3301    return $x->bnan() if $x->{sign} !~ /^\+/ || $y->is_zero() ||
3302      $y->{sign} !~ /^\+$/;
3303
3304    return $x if $x->is_zero() || $x->is_one() || $x->is_inf() || $y->is_one();
3305
3306    # we need to limit the accuracy to protect against overflow
3307    my $fallback = 0;
3308    my (@params, $scale);
3309    ($x, @params) = $x->_find_round_parameters($a, $p, $r);
3310
3311    return $x if $x->is_nan();  # error in _find_round_parameters?
3312
3313    # no rounding at all, so must use fallback
3314    if (scalar @params == 0) {
3315        # simulate old behaviour
3316        $params[0] = $class->div_scale(); # and round to it as accuracy
3317        $scale = $params[0]+4;            # at least four more for proper round
3318        $params[2] = $r;                  # round mode by caller or undef
3319        $fallback = 1;                    # to clear a/p afterwards
3320    } else {
3321        # the 4 below is empirical, and there might be cases where it is not
3322        # enough...
3323        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
3324    }
3325
3326    # when user set globals, they would interfere with our calculation, so
3327    # disable them and later re-enable them
3328    no strict 'refs';
3329    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
3330    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
3331    # we also need to disable any set A or P on $x (_find_round_parameters took
3332    # them already into account), since these would interfere, too
3333    delete $x->{_a};
3334    delete $x->{_p};
3335    # need to disable $upgrade in BigInt, to avoid deep recursion
3336    local $Math::BigInt::upgrade = undef; # should be really parent class vs MBI
3337
3338    # remember sign and make $x positive, since -4 ** (1/2) => -2
3339    my $sign = 0;
3340    $sign = 1 if $x->{sign} eq '-';
3341    $x->{sign} = '+';
3342
3343    my $is_two = 0;
3344    if ($y->isa('Math::BigFloat')) {
3345        $is_two = ($y->{sign} eq '+' && $LIB->_is_two($y->{_m}) && $LIB->_is_zero($y->{_e}));
3346    } else {
3347        $is_two = ($y == 2);
3348    }
3349
3350    # normal square root if $y == 2:
3351    if ($is_two) {
3352        $x->bsqrt($scale+4);
3353    } elsif ($y->is_one('-')) {
3354        # $x ** -1 => 1/$x
3355        my $u = $class->bone()->bdiv($x, $scale);
3356        # copy private parts over
3357        $x->{_m} = $u->{_m};
3358        $x->{_e} = $u->{_e};
3359        $x->{_es} = $u->{_es};
3360    } else {
3361        # calculate the broot() as integer result first, and if it fits, return
3362        # it rightaway (but only if $x and $y are integer):
3363
3364        my $done = 0;           # not yet
3365        if ($y->is_int() && $x->is_int()) {
3366            my $i = $LIB->_copy($x->{_m});
3367            $i = $LIB->_lsft($i, $x->{_e}, 10) unless $LIB->_is_zero($x->{_e});
3368            my $int = Math::BigInt->bzero();
3369            $int->{value} = $i;
3370            $int->broot($y->as_number());
3371            # if ($exact)
3372            if ($int->copy()->bpow($y) == $x) {
3373                # found result, return it
3374                $x->{_m} = $int->{value};
3375                $x->{_e} = $LIB->_zero();
3376                $x->{_es} = '+';
3377                $x->bnorm();
3378                $done = 1;
3379            }
3380        }
3381        if ($done == 0) {
3382            my $u = $class->bone()->bdiv($y, $scale+4);
3383            delete $u->{_a}; delete $u->{_p}; # otherwise it conflicts
3384            $x->bpow($u, $scale+4);            # el cheapo
3385        }
3386    }
3387    $x->bneg() if $sign == 1;
3388
3389    # shortcut to not run through _find_round_parameters again
3390    if (defined $params[0]) {
3391        $x->bround($params[0], $params[2]); # then round accordingly
3392    } else {
3393        $x->bfround($params[1], $params[2]); # then round accordingly
3394    }
3395    if ($fallback) {
3396        # clear a/p after round, since user did not request it
3397        delete $x->{_a};
3398        delete $x->{_p};
3399    }
3400    # restore globals
3401    $$abr = $ab;
3402    $$pbr = $pb;
3403    $x;
3404}
3405
3406sub bfac {
3407    # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
3408    # compute factorial number, modifies first argument
3409
3410    # set up parameters
3411    my ($class, $x, @r) = (ref($_[0]), @_);
3412    # objectify is costly, so avoid it
3413    ($class, $x, @r) = objectify(1, @_) if !ref($x);
3414
3415    # inf => inf
3416    return $x if $x->modify('bfac') || $x->{sign} eq '+inf';
3417
3418    return $x->bnan()
3419      if (($x->{sign} ne '+') || # inf, NaN, <0 etc => NaN
3420          ($x->{_es} ne '+'));   # digits after dot?
3421
3422    if (! $LIB->_is_zero($x->{_e})) {
3423        $x->{_m} = $LIB->_lsft($x->{_m}, $x->{_e}, 10); # change 12e1 to 120e0
3424        $x->{_e} = $LIB->_zero();           # normalize
3425        $x->{_es} = '+';
3426    }
3427    $x->{_m} = $LIB->_fac($x->{_m});       # calculate factorial
3428    $x->bnorm()->round(@r);     # norm again and round result
3429}
3430
3431sub bdfac {
3432    # compute double factorial
3433
3434    # set up parameters
3435    my ($class, $x, @r) = (ref($_[0]), @_);
3436    # objectify is costly, so avoid it
3437    ($class, $x, @r) = objectify(1, @_) if !ref($x);
3438
3439    # inf => inf
3440    return $x if $x->modify('bdfac') || $x->{sign} eq '+inf';
3441
3442    return $x->bnan() if ($x->is_nan() ||
3443                          $x->{_es} ne '+');    # digits after dot?
3444    return $x->bnan() if $x <= -2;
3445    return $x->bone() if $x <= 1;
3446
3447    croak("bdfac() requires a newer version of the $LIB library.")
3448        unless $LIB->can('_dfac');
3449
3450    if (! $LIB->_is_zero($x->{_e})) {
3451        $x->{_m} = $LIB->_lsft($x->{_m}, $x->{_e}, 10); # change 12e1 to 120e0
3452        $x->{_e} = $LIB->_zero();           # normalize
3453        $x->{_es} = '+';
3454    }
3455    $x->{_m} = $LIB->_dfac($x->{_m});       # calculate factorial
3456    $x->bnorm()->round(@r);     # norm again and round result
3457}
3458
3459sub btfac {
3460    # compute triple factorial
3461
3462    # set up parameters
3463    my ($class, $x, @r) = (ref($_[0]), @_);
3464    # objectify is costly, so avoid it
3465    ($class, $x, @r) = objectify(1, @_) if !ref($x);
3466
3467    # inf => inf
3468    return $x if $x->modify('btfac') || $x->{sign} eq '+inf';
3469
3470    return $x->bnan() if ($x->is_nan() ||
3471                          $x->{_es} ne '+');    # digits after dot?
3472
3473    my $k = $class -> new("3");
3474    return $x->bnan() if $x <= -$k;
3475
3476    my $one = $class -> bone();
3477    return $x->bone() if $x <= $one;
3478
3479    my $f = $x -> copy();
3480    while ($f -> bsub($k) > $one) {
3481        $x -> bmul($f);
3482    }
3483    $x->round(@r);
3484}
3485
3486sub bmfac {
3487    my ($class, $x, $k, @r) = objectify(2, @_);
3488
3489    # inf => inf
3490    return $x if $x->modify('bmfac') || $x->{sign} eq '+inf';
3491
3492    return $x->bnan() if ($x->is_nan() || $k->is_nan() ||
3493                          $k < 1 || $x <= -$k ||
3494                          $x->{_es} ne '+' || $k->{_es} ne '+');
3495
3496    return $x->bnan() if $x <= -$k;
3497
3498    my $one = $class -> bone();
3499    return $x->bone() if $x <= $one;
3500
3501    my $f = $x -> copy();
3502    while ($f -> bsub($k) > $one) {
3503        $x -> bmul($f);
3504    }
3505    $x->round(@r);
3506}
3507
3508sub blsft {
3509    # shift left by $y (multiply by $b ** $y)
3510
3511    # set up parameters
3512    my ($class, $x, $y, $b, $a, $p, $r) = (ref($_[0]), @_);
3513
3514    # objectify is costly, so avoid it
3515    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
3516        ($class, $x, $y, $b, $a, $p, $r) = objectify(2, @_);
3517    }
3518
3519    return $x if $x -> modify('blsft');
3520    return $x if $x -> {sign} !~ /^[+-]$/; # nan, +inf, -inf
3521
3522    $b = 2 if !defined $b;
3523    $b = $class -> new($b) unless ref($b) && $b -> isa($class);
3524
3525    return $x -> bnan() if $x -> is_nan() || $y -> is_nan() || $b -> is_nan();
3526
3527    # shift by a negative amount?
3528    return $x -> brsft($y -> copy() -> babs(), $b) if $y -> {sign} =~ /^-/;
3529
3530    $x -> bmul($b -> bpow($y), $a, $p, $r, $y);
3531}
3532
3533sub brsft {
3534    # shift right by $y (divide $b ** $y)
3535
3536    # set up parameters
3537    my ($class, $x, $y, $b, $a, $p, $r) = (ref($_[0]), @_);
3538
3539    # objectify is costly, so avoid it
3540    if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1]))) {
3541        ($class, $x, $y, $b, $a, $p, $r) = objectify(2, @_);
3542    }
3543
3544    return $x if $x -> modify('brsft');
3545    return $x if $x -> {sign} !~ /^[+-]$/; # nan, +inf, -inf
3546
3547    $b = 2 if !defined $b;
3548    $b = $class -> new($b) unless ref($b) && $b -> isa($class);
3549
3550    return $x -> bnan() if $x -> is_nan() || $y -> is_nan() || $b -> is_nan();
3551
3552    # shift by a negative amount?
3553    return $x -> blsft($y -> copy() -> babs(), $b) if $y -> {sign} =~ /^-/;
3554
3555    # the following call to bdiv() will return either quotient (scalar context)
3556    # or quotient and remainder (list context).
3557    $x -> bdiv($b -> bpow($y), $a, $p, $r, $y);
3558}
3559
3560###############################################################################
3561# Bitwise methods
3562###############################################################################
3563
3564sub band {
3565    my $x     = shift;
3566    my $xref  = ref($x);
3567    my $class = $xref || $x;
3568
3569    croak 'band() is an instance method, not a class method' unless $xref;
3570    croak 'Not enough arguments for band()' if @_ < 1;
3571
3572    return if $x -> modify('band');
3573
3574    my $y = shift;
3575    $y = $class -> new($y) unless ref($y);
3576
3577    my @r = @_;
3578
3579    my $xtmp = Math::BigInt -> new($x -> bint());   # to Math::BigInt
3580    $xtmp -> band($y);
3581    $xtmp = $class -> new($xtmp);                   # back to Math::BigFloat
3582
3583    $x -> {sign} = $xtmp -> {sign};
3584    $x -> {_m}   = $xtmp -> {_m};
3585    $x -> {_es}  = $xtmp -> {_es};
3586    $x -> {_e}   = $xtmp -> {_e};
3587
3588    return $x -> round(@r);
3589}
3590
3591sub bior {
3592    my $x     = shift;
3593    my $xref  = ref($x);
3594    my $class = $xref || $x;
3595
3596    croak 'bior() is an instance method, not a class method' unless $xref;
3597    croak 'Not enough arguments for bior()' if @_ < 1;
3598
3599    return if $x -> modify('bior');
3600
3601    my $y = shift;
3602    $y = $class -> new($y) unless ref($y);
3603
3604    my @r = @_;
3605
3606    my $xtmp = Math::BigInt -> new($x -> bint());   # to Math::BigInt
3607    $xtmp -> bior($y);
3608    $xtmp = $class -> new($xtmp);                   # back to Math::BigFloat
3609
3610    $x -> {sign} = $xtmp -> {sign};
3611    $x -> {_m}   = $xtmp -> {_m};
3612    $x -> {_es}  = $xtmp -> {_es};
3613    $x -> {_e}   = $xtmp -> {_e};
3614
3615    return $x -> round(@r);
3616}
3617
3618sub bxor {
3619    my $x     = shift;
3620    my $xref  = ref($x);
3621    my $class = $xref || $x;
3622
3623    croak 'bxor() is an instance method, not a class method' unless $xref;
3624    croak 'Not enough arguments for bxor()' if @_ < 1;
3625
3626    return if $x -> modify('bxor');
3627
3628    my $y = shift;
3629    $y = $class -> new($y) unless ref($y);
3630
3631    my @r = @_;
3632
3633    my $xtmp = Math::BigInt -> new($x -> bint());   # to Math::BigInt
3634    $xtmp -> bxor($y);
3635    $xtmp = $class -> new($xtmp);                   # back to Math::BigFloat
3636
3637    $x -> {sign} = $xtmp -> {sign};
3638    $x -> {_m}   = $xtmp -> {_m};
3639    $x -> {_es}  = $xtmp -> {_es};
3640    $x -> {_e}   = $xtmp -> {_e};
3641
3642    return $x -> round(@r);
3643}
3644
3645sub bnot {
3646    my $x     = shift;
3647    my $xref  = ref($x);
3648    my $class = $xref || $x;
3649
3650    croak 'bnot() is an instance method, not a class method' unless $xref;
3651
3652    return if $x -> modify('bnot');
3653
3654    my @r = @_;
3655
3656    my $xtmp = Math::BigInt -> new($x -> bint());   # to Math::BigInt
3657    $xtmp -> bnot();
3658    $xtmp = $class -> new($xtmp);                   # back to Math::BigFloat
3659
3660    $x -> {sign} = $xtmp -> {sign};
3661    $x -> {_m}   = $xtmp -> {_m};
3662    $x -> {_es}  = $xtmp -> {_es};
3663    $x -> {_e}   = $xtmp -> {_e};
3664
3665    return $x -> round(@r);
3666}
3667
3668###############################################################################
3669# Rounding methods
3670###############################################################################
3671
3672sub bround {
3673    # accuracy: preserve $N digits, and overwrite the rest with 0's
3674    my $x = shift;
3675    my $class = ref($x) || $x;
3676    $x = $class->new(shift) if !ref($x);
3677
3678    if (($_[0] || 0) < 0) {
3679        croak('bround() needs positive accuracy');
3680    }
3681
3682    return $x if $x->modify('bround');
3683
3684    my ($scale, $mode) = $x->_scale_a(@_);
3685    if (!defined $scale) {         # no-op
3686        return $downgrade->new($x) if defined($downgrade)
3687          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3688        return $x;
3689    }
3690
3691    # Scale is now either $x->{_a}, $accuracy, or the input argument. Test
3692    # whether $x already has lower accuracy, do nothing in this case but do
3693    # round if the accuracy is the same, since a math operation might want to
3694    # round a number with A=5 to 5 digits afterwards again
3695
3696    if (defined $x->{_a} && $x->{_a} < $scale) {
3697        return $downgrade->new($x) if defined($downgrade)
3698          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3699        return $x;
3700    }
3701
3702    # scale < 0 makes no sense
3703    # scale == 0 => keep all digits
3704    # never round a +-inf, NaN
3705
3706    if ($scale <= 0 || $x->{sign} !~ /^[+-]$/) {
3707        return $downgrade->new($x) if defined($downgrade)
3708          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3709        return $x;
3710    }
3711
3712    # 1: never round a 0
3713    # 2: if we should keep more digits than the mantissa has, do nothing
3714    if ($x->is_zero() || $LIB->_len($x->{_m}) <= $scale) {
3715        $x->{_a} = $scale if !defined $x->{_a} || $x->{_a} > $scale;
3716        return $downgrade->new($x) if defined($downgrade)
3717          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3718        return $x;
3719    }
3720
3721    # pass sign to bround for '+inf' and '-inf' rounding modes
3722    my $m = bless { sign => $x->{sign}, value => $x->{_m} }, 'Math::BigInt';
3723
3724    $m->bround($scale, $mode);   # round mantissa
3725    $x->{_m} = $m->{value};     # get our mantissa back
3726    $x->{_a} = $scale;          # remember rounding
3727    delete $x->{_p};            # and clear P
3728
3729    # bnorm() downgrades if necessary, so no need to check whether to downgrade.
3730    $x->bnorm();                # del trailing zeros gen. by bround()
3731}
3732
3733sub bfround {
3734    # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
3735    # $n == 0 means round to integer
3736    # expects and returns normalized numbers!
3737    my $x = shift;
3738    my $class = ref($x) || $x;
3739    $x = $class->new(shift) if !ref($x);
3740
3741    return $x if $x->modify('bfround'); # no-op
3742
3743    my ($scale, $mode) = $x->_scale_p(@_);
3744    if (!defined $scale) {
3745        return $downgrade->new($x) if defined($downgrade)
3746          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3747        return $x;
3748    }
3749
3750    # never round a 0, +-inf, NaN
3751
3752    if ($x->is_zero()) {
3753        $x->{_p} = $scale if !defined $x->{_p} || $x->{_p} < $scale; # -3 < -2
3754        return $downgrade->new($x) if defined($downgrade)
3755          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3756        return $x;
3757    }
3758
3759    if ($x->{sign} !~ /^[+-]$/) {
3760        return $downgrade->new($x) if defined($downgrade)
3761          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3762        return $x;
3763    }
3764
3765    # don't round if x already has lower precision
3766    if (defined $x->{_p} && $x->{_p} < 0 && $scale < $x->{_p}) {
3767        return $downgrade->new($x) if defined($downgrade)
3768          && ($x->is_int() || $x->is_inf() || $x->is_nan());
3769        return $x;
3770    }
3771
3772    $x->{_p} = $scale;          # remember round in any case
3773    delete $x->{_a};            # and clear A
3774    if ($scale < 0) {
3775        # round right from the '.'
3776
3777        if ($x->{_es} eq '+') { # e >= 0 => nothing to round
3778            return $downgrade->new($x) if defined($downgrade)
3779              && ($x->is_int() || $x->is_inf() || $x->is_nan());
3780            return $x;
3781        }
3782
3783        $scale = -$scale;           # positive for simplicity
3784        my $len = $LIB->_len($x->{_m}); # length of mantissa
3785
3786        # the following poses a restriction on _e, but if _e is bigger than a
3787        # scalar, you got other problems (memory etc) anyway
3788        my $dad = -(0+ ($x->{_es}.$LIB->_num($x->{_e}))); # digits after dot
3789        my $zad = 0;                                      # zeros after dot
3790        $zad = $dad - $len if (-$dad < -$len); # for 0.00..00xxx style
3791
3792        # print "scale $scale dad $dad zad $zad len $len\n";
3793        # number  bsstr   len zad dad
3794        # 0.123   123e-3    3   0 3
3795        # 0.0123  123e-4    3   1 4
3796        # 0.001   1e-3      1   2 3
3797        # 1.23    123e-2    3   0 2
3798        # 1.2345  12345e-4  5   0 4
3799
3800        # do not round after/right of the $dad
3801
3802        if ($scale > $dad) { # 0.123, scale >= 3 => exit
3803            return $downgrade->new($x) if defined($downgrade)
3804              && ($x->is_int() || $x->is_inf() || $x->is_nan());
3805            return $x;
3806        }
3807
3808        # round to zero if rounding inside the $zad, but not for last zero like:
3809        # 0.0065, scale -2, round last '0' with following '65' (scale == zad case)
3810        if ($scale < $zad) {
3811            return $downgrade->new($x) if defined($downgrade)
3812              && ($x->is_int() || $x->is_inf() || $x->is_nan());
3813            return $x->bzero();
3814        }
3815
3816        if ($scale == $zad) {    # for 0.006, scale -3 and trunc
3817            $scale = -$len;
3818        } else {
3819            # adjust round-point to be inside mantissa
3820            if ($zad != 0) {
3821                $scale = $scale-$zad;
3822            } else {
3823                my $dbd = $len - $dad;
3824                $dbd = 0 if $dbd < 0; # digits before dot
3825                $scale = $dbd+$scale;
3826            }
3827        }
3828    } else {
3829        # round left from the '.'
3830
3831        # 123 => 100 means length(123) = 3 - $scale (2) => 1
3832
3833        my $dbt = $LIB->_len($x->{_m});
3834        # digits before dot
3835        my $dbd = $dbt + ($x->{_es} . $LIB->_num($x->{_e}));
3836        # should be the same, so treat it as this
3837        $scale = 1 if $scale == 0;
3838        # shortcut if already integer
3839        if ($scale == 1 && $dbt <= $dbd) {
3840            return $downgrade->new($x) if defined($downgrade)
3841              && ($x->is_int() || $x->is_inf() || $x->is_nan());
3842            return $x;
3843        }
3844        # maximum digits before dot
3845        ++$dbd;
3846
3847        if ($scale > $dbd) {
3848            # not enough digits before dot, so round to zero
3849            return $downgrade->new($x) if defined($downgrade);
3850            return $x->bzero;
3851        } elsif ($scale == $dbd) {
3852            # maximum
3853            $scale = -$dbt;
3854        } else {
3855            $scale = $dbd - $scale;
3856        }
3857    }
3858
3859    # pass sign to bround for rounding modes '+inf' and '-inf'
3860    my $m = bless { sign => $x->{sign}, value => $x->{_m} }, 'Math::BigInt';
3861    $m->bround($scale, $mode);
3862    $x->{_m} = $m->{value};     # get our mantissa back
3863
3864    # bnorm() downgrades if necessary, so no need to check whether to downgrade.
3865    $x->bnorm();
3866}
3867
3868sub bfloor {
3869    # round towards minus infinity
3870    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3871
3872    return $x if $x->modify('bfloor');
3873
3874    if ($x->{sign} =~ /^[+-]$/) {
3875        # if $x has digits after dot, remove them
3876        if ($x->{_es} eq '-') {
3877            $x->{_m} = $LIB->_rsft($x->{_m}, $x->{_e}, 10);
3878            $x->{_e} = $LIB->_zero();
3879            $x->{_es} = '+';
3880            # increment if negative
3881            $x->{_m} = $LIB->_inc($x->{_m}) if $x->{sign} eq '-';
3882        }
3883        $x->round(@r);
3884    }
3885    return $downgrade->new($x, @r) if defined($downgrade);
3886    return $x;
3887}
3888
3889sub bceil {
3890    # round towards plus infinity
3891    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3892
3893    return $x if $x->modify('bceil');
3894
3895    # if $x has digits after dot, remove them
3896    if ($x->{sign} =~ /^[+-]$/) {
3897        if ($x->{_es} eq '-') {
3898            $x->{_m} = $LIB->_rsft($x->{_m}, $x->{_e}, 10);
3899            $x->{_e} = $LIB->_zero();
3900            $x->{_es} = '+';
3901            if ($x->{sign} eq '+') {
3902                $x->{_m} = $LIB->_inc($x->{_m});        # increment if positive
3903            } else {
3904                $x->{sign} = '+' if $LIB->_is_zero($x->{_m});   # avoid -0
3905            }
3906        }
3907        $x->round(@r);
3908    }
3909
3910    return $downgrade->new($x, @r) if defined($downgrade);
3911    return $x;
3912}
3913
3914sub bint {
3915    # round towards zero
3916    my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3917
3918    return $x if $x->modify('bint');
3919
3920    if ($x->{sign} =~ /^[+-]$/) {
3921        # if $x has digits after the decimal point
3922        if ($x->{_es} eq '-') {
3923            $x->{_m} = $LIB->_rsft($x->{_m}, $x->{_e}, 10); # remove fraction part
3924            $x->{_e} = $LIB->_zero();                       # truncate/normalize
3925            $x->{_es} = '+';                                # abs e
3926            $x->{sign} = '+' if $LIB->_is_zero($x->{_m});   # avoid -0
3927        }
3928        $x->round(@r);
3929    }
3930
3931    return $downgrade->new($x, @r) if defined($downgrade);
3932    return $x;
3933}
3934
3935###############################################################################
3936# Other mathematical methods
3937###############################################################################
3938
3939sub bgcd {
3940    # (BINT or num_str, BINT or num_str) return BINT
3941    # does not modify arguments, but returns new object
3942
3943    unshift @_, __PACKAGE__
3944      unless ref($_[0]) || $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i;
3945
3946    my ($class, @args) = objectify(0, @_);
3947
3948    my $x = shift @args;
3949    $x = ref($x) && $x -> isa($class) ? $x -> copy() : $class -> new($x);
3950    return $class->bnan() unless $x -> is_int();
3951
3952    while (@args) {
3953        my $y = shift @args;
3954        $y = $class->new($y) unless ref($y) && $y -> isa($class);
3955        return $class->bnan() unless $y -> is_int();
3956
3957        # greatest common divisor
3958        while (! $y->is_zero()) {
3959            ($x, $y) = ($y->copy(), $x->copy()->bmod($y));
3960        }
3961
3962        last if $x -> is_one();
3963    }
3964    return $x -> babs();
3965}
3966
3967sub blcm {
3968    # (BFLOAT or num_str, BFLOAT or num_str) return BFLOAT
3969    # does not modify arguments, but returns new object
3970    # Least Common Multiple
3971
3972    unshift @_, __PACKAGE__
3973      unless ref($_[0]) || $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i;
3974
3975    my ($class, @args) = objectify(0, @_);
3976
3977    my $x = shift @args;
3978    $x = ref($x) && $x -> isa($class) ? $x -> copy() : $class -> new($x);
3979    return $class->bnan() if $x->{sign} !~ /^[+-]$/;    # x NaN?
3980
3981    while (@args) {
3982        my $y = shift @args;
3983        $y = $class -> new($y) unless ref($y) && $y -> isa($class);
3984        return $x->bnan() unless $y -> is_int();
3985        my $gcd = $x -> bgcd($y);
3986        $x -> bdiv($gcd) -> bmul($y);
3987    }
3988
3989    return $x -> babs();
3990}
3991
3992###############################################################################
3993# Object property methods
3994###############################################################################
3995
3996sub length {
3997    my $x = shift;
3998    my $class = ref($x) || $x;
3999    $x = $class->new(shift) unless ref($x);
4000
4001    return 1 if $LIB->_is_zero($x->{_m});
4002
4003    my $len = $LIB->_len($x->{_m});
4004    $len += $LIB->_num($x->{_e}) if $x->{_es} eq '+';
4005    if (wantarray()) {
4006        my $t = 0;
4007        $t = $LIB->_num($x->{_e}) if $x->{_es} eq '-';
4008        return ($len, $t);
4009    }
4010    $len;
4011}
4012
4013sub mantissa {
4014    # return a copy of the mantissa
4015    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4016
4017    if ($x->{sign} !~ /^[+-]$/) {
4018        my $s = $x->{sign};
4019        $s =~ s/^\+//;
4020        return Math::BigInt->new($s, undef, undef); # -inf, +inf => +inf
4021    }
4022    my $m = Math::BigInt->new($LIB->_str($x->{_m}), undef, undef);
4023    $m->bneg() if $x->{sign} eq '-';
4024
4025    $m;
4026}
4027
4028sub exponent {
4029    # return a copy of the exponent
4030    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4031
4032    if ($x->{sign} !~ /^[+-]$/) {
4033        my $s = $x->{sign};
4034        $s =~ s/^[+-]//;
4035        return Math::BigInt->new($s, undef, undef); # -inf, +inf => +inf
4036    }
4037    Math::BigInt->new($x->{_es} . $LIB->_str($x->{_e}), undef, undef);
4038}
4039
4040sub parts {
4041    # return a copy of both the exponent and the mantissa
4042    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4043
4044    if ($x->{sign} !~ /^[+-]$/) {
4045        my $s = $x->{sign};
4046        $s =~ s/^\+//;
4047        my $se = $s;
4048        $se =~ s/^-//;
4049        return ($class->new($s), $class->new($se)); # +inf => inf and -inf, +inf => inf
4050    }
4051    my $m = Math::BigInt->bzero();
4052    $m->{value} = $LIB->_copy($x->{_m});
4053    $m->bneg() if $x->{sign} eq '-';
4054    ($m, Math::BigInt->new($x->{_es} . $LIB->_num($x->{_e})));
4055}
4056
4057sub sparts {
4058    my $self  = shift;
4059    my $class = ref $self;
4060
4061    croak("sparts() is an instance method, not a class method")
4062        unless $class;
4063
4064    # Not-a-number.
4065
4066    if ($self -> is_nan()) {
4067        my $mant = $self -> copy();             # mantissa
4068        return $mant unless wantarray;          # scalar context
4069        my $expo = $class -> bnan();            # exponent
4070        return ($mant, $expo);                  # list context
4071    }
4072
4073    # Infinity.
4074
4075    if ($self -> is_inf()) {
4076        my $mant = $self -> copy();             # mantissa
4077        return $mant unless wantarray;          # scalar context
4078        my $expo = $class -> binf('+');         # exponent
4079        return ($mant, $expo);                  # list context
4080    }
4081
4082    # Finite number.
4083
4084    my $mant = $self -> copy() -> bzero();
4085    $mant -> {sign} = $self -> {sign};
4086    $mant -> {_m}   = $LIB->_copy($self -> {_m});
4087    return $mant unless wantarray;
4088
4089    my $expo = $class -> bzero();
4090    $expo -> {sign} = $self -> {_es};
4091    $expo -> {_m}   = $LIB->_copy($self -> {_e});
4092
4093    return ($mant, $expo);
4094}
4095
4096sub nparts {
4097    my $self  = shift;
4098    my $class = ref $self;
4099
4100    croak("nparts() is an instance method, not a class method")
4101        unless $class;
4102
4103    # Not-a-number.
4104
4105    if ($self -> is_nan()) {
4106        my $mant = $self -> copy();             # mantissa
4107        return $mant unless wantarray;          # scalar context
4108        my $expo = $class -> bnan();            # exponent
4109        return ($mant, $expo);                  # list context
4110    }
4111
4112    # Infinity.
4113
4114    if ($self -> is_inf()) {
4115        my $mant = $self -> copy();             # mantissa
4116        return $mant unless wantarray;          # scalar context
4117        my $expo = $class -> binf('+');         # exponent
4118        return ($mant, $expo);                  # list context
4119    }
4120
4121    # Finite number.
4122
4123    my ($mant, $expo) = $self -> sparts();
4124
4125    if ($mant -> bcmp(0)) {
4126        my ($ndigtot, $ndigfrac) = $mant -> length();
4127        my $expo10adj = $ndigtot - $ndigfrac - 1;
4128
4129        if ($expo10adj != 0) {
4130            my $factor  = "1e" . -$expo10adj;
4131            $mant -> bmul($factor);
4132            return $mant unless wantarray;
4133            $expo -> badd($expo10adj);
4134            return ($mant, $expo);
4135        }
4136    }
4137
4138    return $mant unless wantarray;
4139    return ($mant, $expo);
4140}
4141
4142sub eparts {
4143    my $self  = shift;
4144    my $class = ref $self;
4145
4146    croak("eparts() is an instance method, not a class method")
4147        unless $class;
4148
4149    # Not-a-number and Infinity.
4150
4151    return $self -> sparts() if $self -> is_nan() || $self -> is_inf();
4152
4153    # Finite number.
4154
4155    my ($mant, $expo) = $self -> nparts();
4156
4157    my $c = $expo -> copy() -> bmod(3);
4158    $mant -> blsft($c, 10);
4159    return $mant unless wantarray;
4160
4161    $expo -> bsub($c);
4162    return ($mant, $expo);
4163}
4164
4165sub dparts {
4166    my $self  = shift;
4167    my $class = ref $self;
4168
4169    croak("dparts() is an instance method, not a class method")
4170        unless $class;
4171
4172    # Not-a-number and Infinity.
4173
4174    if ($self -> is_nan() || $self -> is_inf()) {
4175        my $int = $self -> copy();
4176        return $int unless wantarray;
4177        my $frc = $class -> bzero();
4178        return ($int, $frc);
4179    }
4180
4181    my $int = $self  -> copy();
4182    my $frc = $class -> bzero();
4183
4184    # If the input has a fraction part.
4185
4186    if ($int->{_es} eq '-') {
4187        $int->{_m} = $LIB -> _rsft($int->{_m}, $int->{_e}, 10);
4188        $int->{_e} = $LIB -> _zero();
4189        $int->{_es} = '+';
4190        $int->{sign} = '+' if $LIB->_is_zero($int->{_m});   # avoid -0
4191
4192        return $int unless wantarray;
4193        $frc = $self -> copy() -> bsub($int);
4194        return ($int, $frc);
4195    }
4196
4197    return $int unless wantarray;
4198    return ($int, $frc);
4199}
4200
4201sub fparts {
4202    my $x = shift;
4203    my $class = ref $x;
4204
4205    croak("fparts() is an instance method") unless $class;
4206
4207    return ($class -> bnan(),
4208            $class -> bnan()) if $x -> is_nan();
4209
4210    return ($class -> binf($x -> sign()),
4211            $class -> bone()) if $x -> is_inf();
4212
4213    return ($class -> bzero(),
4214            $class -> bone()) if $x -> is_zero();
4215
4216    if ($x -> {_es} eq '-') {                   # exponent < 0
4217        my $numer_lib = $LIB -> _copy($x -> {_m});
4218        my $denom_lib = $LIB -> _1ex($x -> {_e});
4219        my $gcd_lib = $LIB -> _gcd($LIB -> _copy($numer_lib), $denom_lib);
4220        $numer_lib = $LIB -> _div($numer_lib, $gcd_lib);
4221        $denom_lib = $LIB -> _div($denom_lib, $gcd_lib);
4222        return ($class -> new($x -> {sign} . $LIB -> _str($numer_lib)),
4223                $class -> new($LIB -> _str($denom_lib)));
4224    }
4225
4226    elsif (! $LIB -> _is_zero($x -> {_e})) {    # exponent > 0
4227        my $numer_lib = $LIB -> _copy($x -> {_m});
4228        $numer_lib = $LIB -> _lsft($numer_lib, $x -> {_e}, 10);
4229        return ($class -> new($x -> {sign} . $LIB -> _str($numer_lib)),
4230                $class -> bone());
4231    }
4232
4233    else {                                      # exponent = 0
4234        return ($class -> new($x -> {sign} . $LIB -> _str($x -> {_m})),
4235                $class -> bone());
4236    }
4237}
4238
4239sub numerator {
4240    my $x = shift;
4241    my $class = ref $x;
4242
4243    croak("numerator() is an instance method") unless $class;
4244
4245    return $class -> bnan()             if $x -> is_nan();
4246    return $class -> binf($x -> sign()) if $x -> is_inf();
4247    return $class -> bzero()            if $x -> is_zero();
4248
4249    if ($x -> {_es} eq '-') {                   # exponent < 0
4250        my $numer_lib = $LIB -> _copy($x -> {_m});
4251        my $denom_lib = $LIB -> _1ex($x -> {_e});
4252        my $gcd_lib = $LIB -> _gcd($LIB -> _copy($numer_lib), $denom_lib);
4253        $numer_lib = $LIB -> _div($numer_lib, $gcd_lib);
4254        return $class -> new($x -> {sign} . $LIB -> _str($numer_lib));
4255    }
4256
4257    elsif (! $LIB -> _is_zero($x -> {_e})) {    # exponent > 0
4258        my $numer_lib = $LIB -> _copy($x -> {_m});
4259        $numer_lib = $LIB -> _lsft($numer_lib, $x -> {_e}, 10);
4260        return $class -> new($x -> {sign} . $LIB -> _str($numer_lib));
4261    }
4262
4263    else {                                      # exponent = 0
4264        return $class -> new($x -> {sign} . $LIB -> _str($x -> {_m}));
4265    }
4266}
4267
4268sub denominator {
4269    my $x = shift;
4270    my $class = ref $x;
4271
4272    croak("denominator() is an instance method") unless $class;
4273
4274    return $class -> bnan() if $x -> is_nan();
4275
4276    if ($x -> {_es} eq '-') {                   # exponent < 0
4277        my $numer_lib = $LIB -> _copy($x -> {_m});
4278        my $denom_lib = $LIB -> _1ex($x -> {_e});
4279        my $gcd_lib = $LIB -> _gcd($LIB -> _copy($numer_lib), $denom_lib);
4280        $denom_lib = $LIB -> _div($denom_lib, $gcd_lib);
4281        return $class -> new($LIB -> _str($denom_lib));
4282    }
4283
4284    else {                                      # exponent >= 0
4285        return $class -> bone();
4286    }
4287}
4288
4289###############################################################################
4290# String conversion methods
4291###############################################################################
4292
4293sub bstr {
4294    # (ref to BFLOAT or num_str) return num_str
4295    # Convert number from internal format to (non-scientific) string format.
4296    # internal format is always normalized (no leading zeros, "-0" => "+0")
4297    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
4298
4299    if ($x->{sign} !~ /^[+-]$/) {
4300        return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4301        return 'inf';                                  # +inf
4302    }
4303
4304    my $es = '0';
4305    my $len = 1;
4306    my $cad = 0;
4307    my $dot = '.';
4308
4309    # $x is zero?
4310    my $not_zero = !($x->{sign} eq '+' && $LIB->_is_zero($x->{_m}));
4311    if ($not_zero) {
4312        $es = $LIB->_str($x->{_m});
4313        $len = CORE::length($es);
4314        my $e = $LIB->_num($x->{_e});
4315        $e = -$e if $x->{_es} eq '-';
4316        if ($e < 0) {
4317            $dot = '';
4318            # if _e is bigger than a scalar, the following will blow your memory
4319            if ($e <= -$len) {
4320                my $r = abs($e) - $len;
4321                $es = '0.'. ('0' x $r) . $es;
4322                $cad = -($len+$r);
4323            } else {
4324                substr($es, $e, 0) = '.';
4325                $cad = $LIB->_num($x->{_e});
4326                $cad = -$cad if $x->{_es} eq '-';
4327            }
4328        } elsif ($e > 0) {
4329            # expand with zeros
4330            $es .= '0' x $e;
4331            $len += $e;
4332            $cad = 0;
4333        }
4334    }                           # if not zero
4335
4336    $es = '-'.$es if $x->{sign} eq '-';
4337    # if set accuracy or precision, pad with zeros on the right side
4338    if ((defined $x->{_a}) && ($not_zero)) {
4339        # 123400 => 6, 0.1234 => 4, 0.001234 => 4
4340        my $zeros = $x->{_a} - $cad; # cad == 0 => 12340
4341        $zeros = $x->{_a} - $len if $cad != $len;
4342        $es .= $dot.'0' x $zeros if $zeros > 0;
4343    } elsif ((($x->{_p} || 0) < 0)) {
4344        # 123400 => 6, 0.1234 => 4, 0.001234 => 6
4345        my $zeros = -$x->{_p} + $cad;
4346        $es .= $dot.'0' x $zeros if $zeros > 0;
4347    }
4348    $es;
4349}
4350
4351# Decimal notation, e.g., "12345.6789".
4352
4353sub bdstr {
4354    my $x = shift;
4355
4356    if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4357        return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4358        return 'inf';                                  # +inf
4359    }
4360
4361    my $mant = $LIB->_str($x->{_m});
4362    my $expo = $x -> exponent();
4363
4364    my $str = $mant;
4365    if ($expo >= 0) {
4366        $str .= "0" x $expo;
4367    } else {
4368        my $mantlen = CORE::length($mant);
4369        my $c = $mantlen + $expo;
4370        $str = "0" x (1 - $c) . $str if $c <= 0;
4371        substr($str, $expo, 0) = '.';
4372    }
4373
4374    return $x->{sign} eq '-' ? "-$str" : $str;
4375}
4376
4377# Scientific notation with significand/mantissa as an integer, e.g., "12345.6789"
4378# is written as "123456789e-4".
4379
4380sub bsstr {
4381    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
4382
4383    if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4384        return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4385        return 'inf';                                  # +inf
4386    }
4387
4388    my $str = $LIB->_str($x->{_m}) . 'e' . $x->{_es}. $LIB->_str($x->{_e});
4389    return $x->{sign} eq '-' ? "-$str" : $str;
4390}
4391
4392# Normalized notation, e.g., "12345.6789" is written as "1.23456789e+4".
4393
4394sub bnstr {
4395    my $x = shift;
4396
4397    if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4398        return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4399        return 'inf';                                  # +inf
4400    }
4401
4402    my ($mant, $expo) = $x -> nparts();
4403
4404    my $esgn = $expo < 0 ? '-' : '+';
4405    my $eabs = $expo -> babs() -> bfround(0) -> bstr();
4406    #$eabs = '0' . $eabs if length($eabs) < 2;
4407
4408    return $mant . 'e' . $esgn . $eabs;
4409}
4410
4411# Engineering notation, e.g., "12345.6789" is written as "12.3456789e+3".
4412
4413sub bestr {
4414    my $x = shift;
4415
4416    if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4417        return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4418        return 'inf';                                  # +inf
4419    }
4420
4421    my ($mant, $expo) = $x -> eparts();
4422
4423    my $esgn = $expo < 0 ? '-' : '+';
4424    my $eabs = $expo -> babs() -> bfround(0) -> bstr();
4425    #$eabs = '0' . $eabs if length($eabs) < 2;
4426
4427    return $mant . 'e' . $esgn . $eabs;
4428}
4429
4430sub to_hex {
4431    # return number as hexadecimal string (only for integers defined)
4432
4433    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4434
4435    return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4436    return '0' if $x->is_zero();
4437
4438    return $nan if $x->{_es} ne '+';    # how to do 1e-1 in hex?
4439
4440    my $z = $LIB->_copy($x->{_m});
4441    if (! $LIB->_is_zero($x->{_e})) {   # > 0
4442        $z = $LIB->_lsft($z, $x->{_e}, 10);
4443    }
4444    my $str = $LIB->_to_hex($z);
4445    return $x->{sign} eq '-' ? "-$str" : $str;
4446}
4447
4448sub to_oct {
4449    # return number as octal digit string (only for integers defined)
4450
4451    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4452
4453    return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4454    return '0' if $x->is_zero();
4455
4456    return $nan if $x->{_es} ne '+';    # how to do 1e-1 in octal?
4457
4458    my $z = $LIB->_copy($x->{_m});
4459    if (! $LIB->_is_zero($x->{_e})) {   # > 0
4460        $z = $LIB->_lsft($z, $x->{_e}, 10);
4461    }
4462    my $str = $LIB->_to_oct($z);
4463    return $x->{sign} eq '-' ? "-$str" : $str;
4464}
4465
4466sub to_bin {
4467    # return number as binary digit string (only for integers defined)
4468
4469    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4470
4471    return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4472    return '0' if $x->is_zero();
4473
4474    return $nan if $x->{_es} ne '+';    # how to do 1e-1 in binary?
4475
4476    my $z = $LIB->_copy($x->{_m});
4477    if (! $LIB->_is_zero($x->{_e})) {   # > 0
4478        $z = $LIB->_lsft($z, $x->{_e}, 10);
4479    }
4480    my $str = $LIB->_to_bin($z);
4481    return $x->{sign} eq '-' ? "-$str" : $str;
4482}
4483
4484sub to_ieee754 {
4485    my $x = shift;
4486    my $format = shift;
4487    my $class = ref $x;
4488
4489    my $enc;            # significand encoding (applies only to decimal)
4490    my $k;              # storage width in bits
4491    my $b;              # base
4492
4493    if ($format =~ /^binary(\d+)\z/) {
4494        $k = $1;
4495        $b = 2;
4496    } elsif ($format =~ /^decimal(\d+)(dpd|bcd)?\z/) {
4497        $k = $1;
4498        $b = 10;
4499        $enc = $2 || 'dpd';     # default is dencely-packed decimals (DPD)
4500    } elsif ($format eq 'half') {
4501        $k = 16;
4502        $b = 2;
4503    } elsif ($format eq 'single') {
4504        $k = 32;
4505        $b = 2;
4506    } elsif ($format eq 'double') {
4507        $k = 64;
4508        $b = 2;
4509    } elsif ($format eq 'quadruple') {
4510        $k = 128;
4511        $b = 2;
4512    } elsif ($format eq 'octuple') {
4513        $k = 256;
4514        $b = 2;
4515    } elsif ($format eq 'sexdecuple') {
4516        $k = 512;
4517        $b = 2;
4518    }
4519
4520    if ($b == 2) {
4521
4522        # Get the parameters for this format.
4523
4524        my $p;                      # precision (in bits)
4525        my $t;                      # number of bits in significand
4526        my $w;                      # number of bits in exponent
4527
4528        if ($k == 16) {             # binary16 (half-precision)
4529            $p = 11;
4530            $t = 10;
4531            $w =  5;
4532        } elsif ($k == 32) {        # binary32 (single-precision)
4533            $p = 24;
4534            $t = 23;
4535            $w =  8;
4536        } elsif ($k == 64) {        # binary64 (double-precision)
4537            $p = 53;
4538            $t = 52;
4539            $w = 11;
4540        } else {                    # binaryN (quadruple-precition and above)
4541            if ($k < 128 || $k != 32 * sprintf('%.0f', $k / 32)) {
4542                croak "Number of bits must be 16, 32, 64, or >= 128 and",
4543                  " a multiple of 32";
4544            }
4545            $p = $k - sprintf('%.0f', 4 * log($k) / log(2)) + 13;
4546            $t = $p - 1;
4547            $w = $k - $t - 1;
4548        }
4549
4550        # The maximum exponent, minimum exponent, and exponent bias.
4551
4552        my $emax = $class -> new(2) -> bpow($w - 1) -> bdec();
4553        my $emin = 1 - $emax;
4554        my $bias = $emax;
4555
4556        # Get numerical sign, exponent, and mantissa/significand for bit
4557        # string.
4558
4559        my $sign = 0;
4560        my $expo;
4561        my $mant;
4562
4563        if ($x -> is_nan()) {                   # nan
4564            $sign = 1;
4565            $expo = $emax -> copy() -> binc();
4566            $mant = $class -> new(2) -> bpow($t - 1);
4567        } elsif ($x -> is_inf()) {              # inf
4568            $sign = 1 if $x -> is_neg();
4569            $expo = $emax -> copy() -> binc();
4570            $mant = $class -> bzero();
4571        } elsif ($x -> is_zero()) {             # zero
4572            $expo = $emin -> copy() -> bdec();
4573            $mant = $class -> bzero();
4574        } else {                                # normal and subnormal
4575
4576            $sign = 1 if $x -> is_neg();
4577
4578            # Now we need to compute the mantissa and exponent in base $b.
4579
4580            my $binv = $class -> new("0.5");
4581            my $b    = $class -> new(2);
4582            my $one  = $class -> bone();
4583
4584            # We start off by initializing the exponent to zero and the
4585            # mantissa to the input value. Then we increase the mantissa and
4586            # decrease the exponent, or vice versa, until the mantissa is in
4587            # the desired range or we hit one of the limits for the exponent.
4588
4589            $mant = $x -> copy() -> babs();
4590
4591            # We need to find the base 2 exponent. First make an estimate of
4592            # the base 2 exponent, before adjusting it below. We could skip
4593            # this estimation and go straight to the while-loops below, but the
4594            # loops are slow, especially when the final exponent is far from
4595            # zero and even more so if the number of digits is large. This
4596            # initial estimation speeds up the computation dramatically.
4597            #
4598            #   log2($m * 10**$e) = log10($m + 10**$e) * log(10)/log(2)
4599            #                     = (log10($m) + $e) * log(10)/log(2)
4600            #                     = (log($m)/log(10) + $e) * log(10)/log(2)
4601
4602            my ($m, $e) = $x -> nparts();
4603            my $ms = $m -> numify();
4604            my $es = $e -> numify();
4605
4606            my $expo_est = (log(abs($ms))/log(10) + $es) * log(10)/log(2);
4607            $expo_est = int($expo_est);
4608
4609            # Limit the exponent.
4610
4611            if ($expo_est > $emax) {
4612                $expo_est = $emax;
4613            } elsif ($expo_est < $emin) {
4614                $expo_est = $emin;
4615            }
4616
4617            # Don't multiply by a number raised to a negative exponent. This
4618            # will cause a division, whose result is truncated to some fixed
4619            # number of digits. Instead, multiply by the inverse number raised
4620            # to a positive exponent.
4621
4622            $expo = $class -> new($expo_est);
4623            if ($expo_est > 0) {
4624                $mant -> bmul($binv -> copy() -> bpow($expo));
4625            } elsif ($expo_est < 0) {
4626                my $expo_abs = $expo -> copy() -> bneg();
4627                $mant -> bmul($b -> copy() -> bpow($expo_abs));
4628            }
4629
4630            # Final adjustment of the estimate above.
4631
4632            while ($mant >= $b && $expo <= $emax) {
4633                $mant -> bmul($binv);
4634                $expo -> binc();
4635            }
4636
4637            while ($mant < $one && $expo >= $emin) {
4638                $mant -> bmul($b);
4639                $expo -> bdec();
4640            }
4641
4642            # This is when the magnitude is larger than what can be represented
4643            # in this format. Encode as infinity.
4644
4645            if ($expo > $emax) {
4646                $mant = $class -> bzero();
4647                $expo = $emax -> copy() -> binc();
4648            }
4649
4650            # This is when the magnitude is so small that the number is encoded
4651            # as a subnormal number.
4652            #
4653            # If the magnitude is smaller than that of the smallest subnormal
4654            # number, and rounded downwards, it is encoded as zero. This works
4655            # transparently and does not need to be treated as a special case.
4656            #
4657            # If the number is between the largest subnormal number and the
4658            # smallest normal number, and the value is rounded upwards, the
4659            # value must be encoded as a normal number. This must be treated as
4660            # a special case.
4661
4662            elsif ($expo < $emin) {
4663
4664                # Scale up the mantissa (significand), and round to integer.
4665
4666                my $const = $class -> new($b) -> bpow($t - 1);
4667                $mant -> bmul($const);
4668                $mant -> bfround(0);
4669
4670                # If the mantissa overflowed, encode as the smallest normal
4671                # number.
4672
4673                if ($mant == $const -> bmul($b)) {
4674                    $mant -> bzero();
4675                    $expo -> binc();
4676                }
4677            }
4678
4679            # This is when the magnitude is within the range of what can be
4680            # encoded as a normal number.
4681
4682            else {
4683
4684                # Remove implicit leading bit, scale up the mantissa
4685                # (significand) to an integer, and round.
4686
4687                $mant -> bdec();
4688                my $const = $class -> new($b) -> bpow($t);
4689                $mant -> bmul($const) -> bfround(0);
4690
4691                # If the mantissa overflowed, encode as the next larger value.
4692                # This works correctly also when the next larger value is
4693                # infinity.
4694
4695                if ($mant == $const) {
4696                    $mant -> bzero();
4697                    $expo -> binc();
4698                }
4699            }
4700        }
4701
4702        $expo -> badd($bias);                   # add bias
4703
4704        my $signbit = "$sign";
4705
4706        my $mantbits = $mant -> to_bin();
4707        $mantbits = ("0" x ($t - CORE::length($mantbits))) . $mantbits;
4708
4709        my $expobits = $expo -> to_bin();
4710        $expobits = ("0" x ($w - CORE::length($expobits))) . $expobits;
4711
4712        my $bin = $signbit . $expobits . $mantbits;
4713        return pack "B*", $bin;
4714    }
4715
4716    croak("The format '$format' is not yet supported.");
4717}
4718
4719sub as_hex {
4720    # return number as hexadecimal string (only for integers defined)
4721
4722    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4723
4724    return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4725    return '0x0' if $x->is_zero();
4726
4727    return $nan if $x->{_es} ne '+';    # how to do 1e-1 in hex?
4728
4729    my $z = $LIB->_copy($x->{_m});
4730    if (! $LIB->_is_zero($x->{_e})) {   # > 0
4731        $z = $LIB->_lsft($z, $x->{_e}, 10);
4732    }
4733    my $str = $LIB->_as_hex($z);
4734    return $x->{sign} eq '-' ? "-$str" : $str;
4735}
4736
4737sub as_oct {
4738    # return number as octal digit string (only for integers defined)
4739
4740    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4741
4742    return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4743    return '00' if $x->is_zero();
4744
4745    return $nan if $x->{_es} ne '+';    # how to do 1e-1 in octal?
4746
4747    my $z = $LIB->_copy($x->{_m});
4748    if (! $LIB->_is_zero($x->{_e})) {   # > 0
4749        $z = $LIB->_lsft($z, $x->{_e}, 10);
4750    }
4751    my $str = $LIB->_as_oct($z);
4752    return $x->{sign} eq '-' ? "-$str" : $str;
4753}
4754
4755sub as_bin {
4756    # return number as binary digit string (only for integers defined)
4757
4758    my ($class, $x) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
4759
4760    return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4761    return '0b0' if $x->is_zero();
4762
4763    return $nan if $x->{_es} ne '+';    # how to do 1e-1 in binary?
4764
4765    my $z = $LIB->_copy($x->{_m});
4766    if (! $LIB->_is_zero($x->{_e})) {   # > 0
4767        $z = $LIB->_lsft($z, $x->{_e}, 10);
4768    }
4769    my $str = $LIB->_as_bin($z);
4770    return $x->{sign} eq '-' ? "-$str" : $str;
4771}
4772
4773sub numify {
4774    # Make a Perl scalar number from a Math::BigFloat object.
4775    my ($class, $x) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
4776
4777    if ($x -> is_nan()) {
4778        require Math::Complex;
4779        my $inf = $Math::Complex::Inf;
4780        return $inf - $inf;
4781    }
4782
4783    if ($x -> is_inf()) {
4784        require Math::Complex;
4785        my $inf = $Math::Complex::Inf;
4786        return $x -> is_negative() ? -$inf : $inf;
4787    }
4788
4789    # Create a string and let Perl's atoi()/atof() handle the rest.
4790    return 0 + $x -> bnstr();
4791}
4792
4793###############################################################################
4794# Private methods and functions.
4795###############################################################################
4796
4797sub import {
4798    my $class = shift;
4799    $IMPORT++;                  # remember we did import()
4800
4801    my @import = ('objectify');
4802    my @a;                      # unrecognized arguments
4803
4804    while (@_) {
4805        my $param = shift;
4806
4807        # Enable overloading of constants.
4808
4809        if ($param eq ':constant') {
4810            overload::constant
4811
4812                integer => sub {
4813                    $class -> new(shift);
4814                },
4815
4816                float   => sub {
4817                    $class -> new(shift);
4818                },
4819
4820                binary  => sub {
4821                    # E.g., a literal 0377 shall result in an object whose value
4822                    # is decimal 255, but new("0377") returns decimal 377.
4823                    return $class -> from_oct($_[0]) if $_[0] =~ /^0_*[0-7]/;
4824                    $class -> new(shift);
4825                };
4826            next;
4827        }
4828
4829        # Upgrading.
4830
4831        if ($param eq 'upgrade') {
4832            $class -> upgrade(shift);
4833            next;
4834        }
4835
4836        # Downgrading.
4837
4838        if ($param eq 'downgrade') {
4839            $class -> downgrade(shift);
4840            next;
4841        }
4842
4843        # Accuracy.
4844
4845        if ($param eq 'accuracy') {
4846            $class -> accuracy(shift);
4847            next;
4848        }
4849
4850        # Precision.
4851
4852        if ($param eq 'precision') {
4853            $class -> precision(shift);
4854            next;
4855        }
4856
4857        # Rounding mode.
4858
4859        if ($param eq 'round_mode') {
4860            $class -> round_mode(shift);
4861            next;
4862        }
4863
4864        # Backend library.
4865
4866        if ($param =~ /^(lib|try|only)\z/) {
4867            push @import, $param;
4868            push @import, shift() if @_;
4869            next;
4870        }
4871
4872        if ($param eq 'with') {
4873            # alternative class for our private parts()
4874            # XXX: no longer supported
4875            # $LIB = shift() || 'Calc';
4876            # carp "'with' is no longer supported, use 'lib', 'try', or 'only'";
4877            shift;
4878            next;
4879        }
4880
4881        # Unrecognized parameter.
4882
4883        push @a, $param;
4884    }
4885
4886    Math::BigInt -> import(@import);
4887
4888    # find out which one was actually loaded
4889    $LIB = Math::BigInt -> config('lib');
4890
4891    $class->export_to_level(1, $class, @a); # export wanted functions
4892}
4893
4894sub _len_to_steps {
4895    # Given D (digits in decimal), compute N so that N! (N factorial) is
4896    # at least D digits long. D should be at least 50.
4897    my $d = shift;
4898
4899    # two constants for the Ramanujan estimate of ln(N!)
4900    my $lg2 = log(2 * 3.14159265) / 2;
4901    my $lg10 = log(10);
4902
4903    # D = 50 => N => 42, so L = 40 and R = 50
4904    my $l = 40;
4905    my $r = $d;
4906
4907    # Otherwise this does not work under -Mbignum and we do not yet have "no bignum;" :(
4908    $l = $l->numify if ref($l);
4909    $r = $r->numify if ref($r);
4910    $lg2 = $lg2->numify if ref($lg2);
4911    $lg10 = $lg10->numify if ref($lg10);
4912
4913    # binary search for the right value (could this be written as the reverse of lg(n!)?)
4914    while ($r - $l > 1) {
4915        my $n = int(($r - $l) / 2) + $l;
4916        my $ramanujan =
4917          int(($n * log($n) - $n + log($n * (1 + 4*$n*(1+2*$n))) / 6 + $lg2) / $lg10);
4918        $ramanujan > $d ? $r = $n : $l = $n;
4919    }
4920    $l;
4921}
4922
4923sub _log {
4924    # internal log function to calculate ln() based on Taylor series.
4925    # Modifies $x in place.
4926    my ($x, $scale) = @_;
4927    my $class = ref $x;
4928
4929    # in case of $x == 1, result is 0
4930    return $x->bzero() if $x->is_one();
4931
4932    # XXX TODO: rewrite this in a similar manner to bexp()
4933
4934    # http://www.efunda.com/math/taylor_series/logarithmic.cfm?search_string=log
4935
4936    # u = x-1, v = x+1
4937    #              _                               _
4938    # Taylor:     |    u    1   u^3   1   u^5       |
4939    # ln (x)  = 2 |   --- + - * --- + - * --- + ... |  x > 0
4940    #             |_   v    3   v^3   5   v^5      _|
4941
4942    # This takes much more steps to calculate the result and is thus not used
4943    # u = x-1
4944    #              _                               _
4945    # Taylor:     |    u    1   u^2   1   u^3       |
4946    # ln (x)  = 2 |   --- + - * --- + - * --- + ... |  x > 1/2
4947    #             |_   x    2   x^2   3   x^3      _|
4948
4949    my ($limit, $v, $u, $below, $factor, $next, $over, $f);
4950
4951    $v = $x->copy(); $v->binc(); # v = x+1
4952    $x->bdec(); $u = $x->copy(); # u = x-1; x = x-1
4953    $x->bdiv($v, $scale);        # first term: u/v
4954    $below = $v->copy();
4955    $over = $u->copy();
4956    $u *= $u; $v *= $v;         # u^2, v^2
4957    $below->bmul($v);           # u^3, v^3
4958    $over->bmul($u);
4959    $factor = $class->new(3); $f = $class->new(2);
4960
4961    $limit = $class->new("1E-". ($scale-1));
4962
4963    while (3 < 5) {
4964        # we calculate the next term, and add it to the last
4965        # when the next term is below our limit, it won't affect the outcome
4966        # anymore, so we stop
4967
4968        # calculating the next term simple from over/below will result in quite
4969        # a time hog if the input has many digits, since over and below will
4970        # accumulate more and more digits, and the result will also have many
4971        # digits, but in the end it is rounded to $scale digits anyway. So if we
4972        # round $over and $below first, we save a lot of time for the division
4973        # (not with log(1.2345), but try log (123**123) to see what I mean. This
4974        # can introduce a rounding error if the division result would be f.i.
4975        # 0.1234500000001 and we round it to 5 digits it would become 0.12346, but
4976        # if we truncated $over and $below we might get 0.12345. Does this matter
4977        # for the end result? So we give $over and $below 4 more digits to be
4978        # on the safe side (unscientific error handling as usual... :+D
4979
4980        $next = $over->copy()->bround($scale+4)
4981          ->bdiv($below->copy()->bmul($factor)->bround($scale+4),
4982                 $scale);
4983
4984        ## old version:
4985        ##    $next = $over->copy()->bdiv($below->copy()->bmul($factor), $scale);
4986
4987        last if $next->bacmp($limit) <= 0;
4988
4989        delete $next->{_a};
4990        delete $next->{_p};
4991        $x->badd($next);
4992        # calculate things for the next term
4993        $over *= $u;
4994        $below *= $v;
4995        $factor->badd($f);
4996    }
4997    $x->bmul($f);               # $x *= 2
4998}
4999
5000sub _log_10 {
5001    # Internal log function based on reducing input to the range of 0.1 .. 9.99
5002    # and then "correcting" the result to the proper one. Modifies $x in place.
5003    my ($x, $scale) = @_;
5004    my $class = ref $x;
5005
5006    # Taking blog() from numbers greater than 10 takes a *very long* time, so we
5007    # break the computation down into parts based on the observation that:
5008    #  blog(X*Y) = blog(X) + blog(Y)
5009    # We set Y here to multiples of 10 so that $x becomes below 1 - the smaller
5010    # $x is the faster it gets. Since 2*$x takes about 10 times as
5011    # long, we make it faster by about a factor of 100 by dividing $x by 10.
5012
5013    # The same observation is valid for numbers smaller than 0.1, e.g. computing
5014    # log(1) is fastest, and the further away we get from 1, the longer it takes.
5015    # So we also 'break' this down by multiplying $x with 10 and subtract the
5016    # log(10) afterwards to get the correct result.
5017
5018    # To get $x even closer to 1, we also divide by 2 and then use log(2) to
5019    # correct for this. For instance if $x is 2.4, we use the formula:
5020    #  blog(2.4 * 2) == blog(1.2) + blog(2)
5021    # and thus calculate only blog(1.2) and blog(2), which is faster in total
5022    # than calculating blog(2.4).
5023
5024    # In addition, the values for blog(2) and blog(10) are cached.
5025
5026    # Calculate nr of digits before dot. x = 123, dbd = 3; x = 1.23, dbd = 1;
5027    # x = 0.0123, dbd = -1; x = 0.000123, dbd = -3, etc.
5028
5029    my $dbd = $LIB->_num($x->{_e});
5030    $dbd = -$dbd if $x->{_es} eq '-';
5031    $dbd += $LIB->_len($x->{_m});
5032
5033    # more than one digit (e.g. at least 10), but *not* exactly 10 to avoid
5034    # infinite recursion
5035
5036    my $calc = 1;               # do some calculation?
5037
5038    # disable the shortcut for 10, since we need log(10) and this would recurse
5039    # infinitely deep
5040    if ($x->{_es} eq '+' &&                     # $x == 10
5041        ($LIB->_is_one($x->{_e}) &&
5042         $LIB->_is_one($x->{_m})))
5043    {
5044        $dbd = 0;               # disable shortcut
5045        # we can use the cached value in these cases
5046        if ($scale <= $LOG_10_A) {
5047            $x->bzero();
5048            $x->badd($LOG_10); # modify $x in place
5049            $calc = 0;                      # no need to calc, but round
5050        }
5051        # if we can't use the shortcut, we continue normally
5052    } else {
5053        # disable the shortcut for 2, since we maybe have it cached
5054        if (($LIB->_is_zero($x->{_e}) &&        # $x == 2
5055             $LIB->_is_two($x->{_m})))
5056        {
5057            $dbd = 0;           # disable shortcut
5058            # we can use the cached value in these cases
5059            if ($scale <= $LOG_2_A) {
5060                $x->bzero();
5061                $x->badd($LOG_2); # modify $x in place
5062                $calc = 0;                     # no need to calc, but round
5063            }
5064            # if we can't use the shortcut, we continue normally
5065        }
5066    }
5067
5068    # if $x = 0.1, we know the result must be 0-log(10)
5069    if ($calc != 0 &&
5070        ($x->{_es} eq '-' &&                    # $x == 0.1
5071         ($LIB->_is_one($x->{_e}) &&
5072          $LIB->_is_one($x->{_m}))))
5073    {
5074        $dbd = 0;               # disable shortcut
5075        # we can use the cached value in these cases
5076        if ($scale <= $LOG_10_A) {
5077            $x->bzero();
5078            $x->bsub($LOG_10);
5079            $calc = 0;          # no need to calc, but round
5080        }
5081    }
5082
5083    return $x if $calc == 0;    # already have the result
5084
5085    # default: these correction factors are undef and thus not used
5086    my $l_10;                   # value of ln(10) to A of $scale
5087    my $l_2;                    # value of ln(2) to A of $scale
5088
5089    my $two = $class->new(2);
5090
5091    # $x == 2 => 1, $x == 13 => 2, $x == 0.1 => 0, $x == 0.01 => -1
5092    # so don't do this shortcut for 1 or 0
5093    if (($dbd > 1) || ($dbd < 0)) {
5094        # convert our cached value to an object if not already (avoid doing this
5095        # at import() time, since not everybody needs this)
5096        $LOG_10 = $class->new($LOG_10, undef, undef) unless ref $LOG_10;
5097
5098        #print "x = $x, dbd = $dbd, calc = $calc\n";
5099        # got more than one digit before the dot, or more than one zero after the
5100        # dot, so do:
5101        #  log(123)    == log(1.23) + log(10) * 2
5102        #  log(0.0123) == log(1.23) - log(10) * 2
5103
5104        if ($scale <= $LOG_10_A) {
5105            # use cached value
5106            $l_10 = $LOG_10->copy(); # copy for mul
5107        } else {
5108            # else: slower, compute and cache result
5109            # also disable downgrade for this code path
5110            local $Math::BigFloat::downgrade = undef;
5111
5112            # shorten the time to calculate log(10) based on the following:
5113            # log(1.25 * 8) = log(1.25) + log(8)
5114            #               = log(1.25) + log(2) + log(2) + log(2)
5115
5116            # first get $l_2 (and possible compute and cache log(2))
5117            $LOG_2 = $class->new($LOG_2, undef, undef) unless ref $LOG_2;
5118            if ($scale <= $LOG_2_A) {
5119                # use cached value
5120                $l_2 = $LOG_2->copy(); # copy() for the mul below
5121            } else {
5122                # else: slower, compute and cache result
5123                $l_2 = $two->copy();
5124                $l_2->_log($scale); # scale+4, actually
5125                $LOG_2 = $l_2->copy(); # cache the result for later
5126                # the copy() is for mul below
5127                $LOG_2_A = $scale;
5128            }
5129
5130            # now calculate log(1.25):
5131            $l_10 = $class->new('1.25');
5132            $l_10->_log($scale); # scale+4, actually
5133
5134            # log(1.25) + log(2) + log(2) + log(2):
5135            $l_10->badd($l_2);
5136            $l_10->badd($l_2);
5137            $l_10->badd($l_2);
5138            $LOG_10 = $l_10->copy(); # cache the result for later
5139            # the copy() is for mul below
5140            $LOG_10_A = $scale;
5141        }
5142        $dbd-- if ($dbd > 1);       # 20 => dbd=2, so make it dbd=1
5143        $l_10->bmul($class->new($dbd)); # log(10) * (digits_before_dot-1)
5144        my $dbd_sign = '+';
5145        if ($dbd < 0) {
5146            $dbd = -$dbd;
5147            $dbd_sign = '-';
5148        }
5149        ($x->{_e}, $x->{_es}) =
5150          _e_sub($x->{_e}, $LIB->_new($dbd), $x->{_es}, $dbd_sign); # 123 => 1.23
5151        #($x->{_e}, $x->{_es}) =
5152        #  $LIB -> _ssub($x->{_e}, $x->{_es}, $LIB->_new($dbd), $dbd_sign);
5153    }
5154
5155    # Now: 0.1 <= $x < 10 (and possible correction in l_10)
5156
5157    ### Since $x in the range 0.5 .. 1.5 is MUCH faster, we do a repeated div
5158    ### or mul by 2 (maximum times 3, since x < 10 and x > 0.1)
5159
5160    $HALF = $class->new($HALF) unless ref($HALF);
5161
5162    my $twos = 0;               # default: none (0 times)
5163    while ($x->bacmp($HALF) <= 0) { # X <= 0.5
5164        $twos--;
5165        $x->bmul($two);
5166    }
5167    while ($x->bacmp($two) >= 0) { # X >= 2
5168        $twos++;
5169        $x->bdiv($two, $scale+4); # keep all digits
5170    }
5171    $x->bround($scale+4);
5172    # $twos > 0 => did mul 2, < 0 => did div 2 (but we never did both)
5173    # So calculate correction factor based on ln(2):
5174    if ($twos != 0) {
5175        $LOG_2 = $class->new($LOG_2, undef, undef) unless ref $LOG_2;
5176        if ($scale <= $LOG_2_A) {
5177            # use cached value
5178            $l_2 = $LOG_2->copy(); # copy() for the mul below
5179        } else {
5180            # else: slower, compute and cache result
5181            # also disable downgrade for this code path
5182            local $Math::BigFloat::downgrade = undef;
5183            $l_2 = $two->copy();
5184            $l_2->_log($scale); # scale+4, actually
5185            $LOG_2 = $l_2->copy(); # cache the result for later
5186            # the copy() is for mul below
5187            $LOG_2_A = $scale;
5188        }
5189        $l_2->bmul($twos);      # * -2 => subtract, * 2 => add
5190    } else {
5191        undef $l_2;
5192    }
5193
5194    $x->_log($scale);       # need to do the "normal" way
5195    $x->badd($l_10) if defined $l_10; # correct it by ln(10)
5196    $x->badd($l_2) if defined $l_2;   # and maybe by ln(2)
5197
5198    # all done, $x contains now the result
5199    $x;
5200}
5201
5202sub _e_add {
5203    # Internal helper sub to take two positive integers and their signs and
5204    # then add them. Input ($LIB, $LIB, ('+'|'-'), ('+'|'-')), output
5205    # ($LIB, ('+'|'-')).
5206
5207    my ($x, $y, $xs, $ys) = @_;
5208
5209    # if the signs are equal we can add them (-5 + -3 => -(5 + 3) => -8)
5210    if ($xs eq $ys) {
5211        $x = $LIB->_add($x, $y); # +a + +b or -a + -b
5212    } else {
5213        my $a = $LIB->_acmp($x, $y);
5214        if ($a == 0) {
5215            # This does NOT modify $x in-place. TODO: Fix this?
5216            $x = $LIB->_zero(); # result is 0
5217            $xs = '+';
5218            return ($x, $xs);
5219        }
5220        if ($a > 0) {
5221            $x = $LIB->_sub($x, $y);     # abs sub
5222        } else {                         # a < 0
5223            $x = $LIB->_sub ($y, $x, 1); # abs sub
5224            $xs = $ys;
5225        }
5226    }
5227
5228    $xs = '+' if $xs eq '-' && $LIB->_is_zero($x); # no "-0"
5229
5230    return ($x, $xs);
5231}
5232
5233sub _e_sub {
5234    # Internal helper sub to take two positive integers and their signs and
5235    # then subtract them. Input ($LIB, $LIB, ('+'|'-'), ('+'|'-')),
5236    # output ($LIB, ('+'|'-'))
5237    my ($x, $y, $xs, $ys) = @_;
5238
5239    # flip sign
5240    $ys = $ys eq '+' ? '-' : '+'; # swap sign of second operand ...
5241    _e_add($x, $y, $xs, $ys);     # ... and let _e_add() do the job
5242    #$LIB -> _sadd($x, $xs, $y, $ys);     # ... and let $LIB -> _sadd() do the job
5243}
5244
5245sub _pow {
5246    # Calculate a power where $y is a non-integer, like 2 ** 0.3
5247    my ($x, $y, @r) = @_;
5248    my $class = ref($x);
5249
5250    # if $y == 0.5, it is sqrt($x)
5251    $HALF = $class->new($HALF) unless ref($HALF);
5252    return $x->bsqrt(@r, $y) if $y->bcmp($HALF) == 0;
5253
5254    # Using:
5255    # a ** x == e ** (x * ln a)
5256
5257    # u = y * ln x
5258    #                _                         _
5259    # Taylor:       |   u    u^2    u^3         |
5260    # x ** y  = 1 + |  --- + --- + ----- + ...  |
5261    #               |_  1    1*2   1*2*3       _|
5262
5263    # we need to limit the accuracy to protect against overflow
5264    my $fallback = 0;
5265    my ($scale, @params);
5266    ($x, @params) = $x->_find_round_parameters(@r);
5267
5268    return $x if $x->is_nan();  # error in _find_round_parameters?
5269
5270    # no rounding at all, so must use fallback
5271    if (scalar @params == 0) {
5272        # simulate old behaviour
5273        $params[0] = $class->div_scale(); # and round to it as accuracy
5274        $params[1] = undef;               # disable P
5275        $scale = $params[0]+4;            # at least four more for proper round
5276        $params[2] = $r[2];               # round mode by caller or undef
5277        $fallback = 1;                    # to clear a/p afterwards
5278    } else {
5279        # the 4 below is empirical, and there might be cases where it is not
5280        # enough...
5281        $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
5282    }
5283
5284    # when user set globals, they would interfere with our calculation, so
5285    # disable them and later re-enable them
5286    no strict 'refs';
5287    my $abr = "$class\::accuracy"; my $ab = $$abr; $$abr = undef;
5288    my $pbr = "$class\::precision"; my $pb = $$pbr; $$pbr = undef;
5289    # we also need to disable any set A or P on $x (_find_round_parameters took
5290    # them already into account), since these would interfere, too
5291    delete $x->{_a};
5292    delete $x->{_p};
5293    # need to disable $upgrade in BigInt, to avoid deep recursion
5294    local $Math::BigInt::upgrade = undef;
5295
5296    my ($limit, $v, $u, $below, $factor, $next, $over);
5297
5298    $u = $x->copy()->blog(undef, $scale)->bmul($y);
5299    my $do_invert = ($u->{sign} eq '-');
5300    $u->bneg()  if $do_invert;
5301    $v = $class->bone();        # 1
5302    $factor = $class->new(2);   # 2
5303    $x->bone();                 # first term: 1
5304
5305    $below = $v->copy();
5306    $over = $u->copy();
5307
5308    $limit = $class->new("1E-". ($scale-1));
5309    while (3 < 5) {
5310        # we calculate the next term, and add it to the last
5311        # when the next term is below our limit, it won't affect the outcome
5312        # anymore, so we stop:
5313        $next = $over->copy()->bdiv($below, $scale);
5314        last if $next->bacmp($limit) <= 0;
5315        $x->badd($next);
5316        # calculate things for the next term
5317        $over *= $u;
5318        $below *= $factor;
5319        $factor->binc();
5320
5321        last if $x->{sign} !~ /^[-+]$/;
5322    }
5323
5324    if ($do_invert) {
5325        my $x_copy = $x->copy();
5326        $x->bone->bdiv($x_copy, $scale);
5327    }
5328
5329    # shortcut to not run through _find_round_parameters again
5330    if (defined $params[0]) {
5331        $x->bround($params[0], $params[2]); # then round accordingly
5332    } else {
5333        $x->bfround($params[1], $params[2]); # then round accordingly
5334    }
5335    if ($fallback) {
5336        # clear a/p after round, since user did not request it
5337        delete $x->{_a};
5338        delete $x->{_p};
5339    }
5340    # restore globals
5341    $$abr = $ab;
5342    $$pbr = $pb;
5343    $x;
5344}
5345
53461;
5347
5348__END__
5349
5350=pod
5351
5352=head1 NAME
5353
5354Math::BigFloat - arbitrary size floating point math package
5355
5356=head1 SYNOPSIS
5357
5358  use Math::BigFloat;
5359
5360  # Configuration methods (may be used as class methods and instance methods)
5361
5362  Math::BigFloat->accuracy();     # get class accuracy
5363  Math::BigFloat->accuracy($n);   # set class accuracy
5364  Math::BigFloat->precision();    # get class precision
5365  Math::BigFloat->precision($n);  # set class precision
5366  Math::BigFloat->round_mode();   # get class rounding mode
5367  Math::BigFloat->round_mode($m); # set global round mode, must be one of
5368                                  # 'even', 'odd', '+inf', '-inf', 'zero',
5369                                  # 'trunc', or 'common'
5370  Math::BigFloat->config("lib");  # name of backend math library
5371
5372  # Constructor methods (when the class methods below are used as instance
5373  # methods, the value is assigned the invocand)
5374
5375  $x = Math::BigFloat->new($str);               # defaults to 0
5376  $x = Math::BigFloat->new('0x123');            # from hexadecimal
5377  $x = Math::BigFloat->new('0o377');            # from octal
5378  $x = Math::BigFloat->new('0b101');            # from binary
5379  $x = Math::BigFloat->from_hex('0xc.afep+3');  # from hex
5380  $x = Math::BigFloat->from_hex('cafe');        # ditto
5381  $x = Math::BigFloat->from_oct('1.3267p-4');   # from octal
5382  $x = Math::BigFloat->from_oct('01.3267p-4');  # ditto
5383  $x = Math::BigFloat->from_oct('0o1.3267p-4'); # ditto
5384  $x = Math::BigFloat->from_oct('0377');        # ditto
5385  $x = Math::BigFloat->from_bin('0b1.1001p-4'); # from binary
5386  $x = Math::BigFloat->from_bin('0101');        # ditto
5387  $x = Math::BigFloat->from_ieee754($b, "binary64");  # from IEEE-754 bytes
5388  $x = Math::BigFloat->bzero();                 # create a +0
5389  $x = Math::BigFloat->bone();                  # create a +1
5390  $x = Math::BigFloat->bone('-');               # create a -1
5391  $x = Math::BigFloat->binf();                  # create a +inf
5392  $x = Math::BigFloat->binf('-');               # create a -inf
5393  $x = Math::BigFloat->bnan();                  # create a Not-A-Number
5394  $x = Math::BigFloat->bpi();                   # returns pi
5395
5396  $y = $x->copy();        # make a copy (unlike $y = $x)
5397  $y = $x->as_int();      # return as BigInt
5398
5399  # Boolean methods (these don't modify the invocand)
5400
5401  $x->is_zero();          # if $x is 0
5402  $x->is_one();           # if $x is +1
5403  $x->is_one("+");        # ditto
5404  $x->is_one("-");        # if $x is -1
5405  $x->is_inf();           # if $x is +inf or -inf
5406  $x->is_inf("+");        # if $x is +inf
5407  $x->is_inf("-");        # if $x is -inf
5408  $x->is_nan();           # if $x is NaN
5409
5410  $x->is_positive();      # if $x > 0
5411  $x->is_pos();           # ditto
5412  $x->is_negative();      # if $x < 0
5413  $x->is_neg();           # ditto
5414
5415  $x->is_odd();           # if $x is odd
5416  $x->is_even();          # if $x is even
5417  $x->is_int();           # if $x is an integer
5418
5419  # Comparison methods
5420
5421  $x->bcmp($y);           # compare numbers (undef, < 0, == 0, > 0)
5422  $x->bacmp($y);          # compare absolutely (undef, < 0, == 0, > 0)
5423  $x->beq($y);            # true if and only if $x == $y
5424  $x->bne($y);            # true if and only if $x != $y
5425  $x->blt($y);            # true if and only if $x < $y
5426  $x->ble($y);            # true if and only if $x <= $y
5427  $x->bgt($y);            # true if and only if $x > $y
5428  $x->bge($y);            # true if and only if $x >= $y
5429
5430  # Arithmetic methods
5431
5432  $x->bneg();             # negation
5433  $x->babs();             # absolute value
5434  $x->bsgn();             # sign function (-1, 0, 1, or NaN)
5435  $x->bnorm();            # normalize (no-op)
5436  $x->binc();             # increment $x by 1
5437  $x->bdec();             # decrement $x by 1
5438  $x->badd($y);           # addition (add $y to $x)
5439  $x->bsub($y);           # subtraction (subtract $y from $x)
5440  $x->bmul($y);           # multiplication (multiply $x by $y)
5441  $x->bmuladd($y,$z);     # $x = $x * $y + $z
5442  $x->bdiv($y);           # division (floored), set $x to quotient
5443                          # return (quo,rem) or quo if scalar
5444  $x->btdiv($y);          # division (truncated), set $x to quotient
5445                          # return (quo,rem) or quo if scalar
5446  $x->bmod($y);           # modulus (x % y)
5447  $x->btmod($y);          # modulus (truncated)
5448  $x->bmodinv($mod);      # modular multiplicative inverse
5449  $x->bmodpow($y,$mod);   # modular exponentiation (($x ** $y) % $mod)
5450  $x->bpow($y);           # power of arguments (x ** y)
5451  $x->blog();             # logarithm of $x to base e (Euler's number)
5452  $x->blog($base);        # logarithm of $x to base $base (e.g., base 2)
5453  $x->bexp();             # calculate e ** $x where e is Euler's number
5454  $x->bnok($y);           # x over y (binomial coefficient n over k)
5455  $x->bsin();             # sine
5456  $x->bcos();             # cosine
5457  $x->batan();            # inverse tangent
5458  $x->batan2($y);         # two-argument inverse tangent
5459  $x->bsqrt();            # calculate square root
5460  $x->broot($y);          # $y'th root of $x (e.g. $y == 3 => cubic root)
5461  $x->bfac();             # factorial of $x (1*2*3*4*..$x)
5462
5463  $x->blsft($n);          # left shift $n places in base 2
5464  $x->blsft($n,$b);       # left shift $n places in base $b
5465                          # returns (quo,rem) or quo (scalar context)
5466  $x->brsft($n);          # right shift $n places in base 2
5467  $x->brsft($n,$b);       # right shift $n places in base $b
5468                          # returns (quo,rem) or quo (scalar context)
5469
5470  # Bitwise methods
5471
5472  $x->band($y);           # bitwise and
5473  $x->bior($y);           # bitwise inclusive or
5474  $x->bxor($y);           # bitwise exclusive or
5475  $x->bnot();             # bitwise not (two's complement)
5476
5477  # Rounding methods
5478  $x->round($A,$P,$mode); # round to accuracy or precision using
5479                          # rounding mode $mode
5480  $x->bround($n);         # accuracy: preserve $n digits
5481  $x->bfround($n);        # $n > 0: round to $nth digit left of dec. point
5482                          # $n < 0: round to $nth digit right of dec. point
5483  $x->bfloor();           # round towards minus infinity
5484  $x->bceil();            # round towards plus infinity
5485  $x->bint();             # round towards zero
5486
5487  # Other mathematical methods
5488
5489  $x->bgcd($y);            # greatest common divisor
5490  $x->blcm($y);            # least common multiple
5491
5492  # Object property methods (do not modify the invocand)
5493
5494  $x->sign();              # the sign, either +, - or NaN
5495  $x->digit($n);           # the nth digit, counting from the right
5496  $x->digit(-$n);          # the nth digit, counting from the left
5497  $x->length();            # return number of digits in number
5498  ($xl,$f) = $x->length(); # length of number and length of fraction
5499                           # part, latter is always 0 digits long
5500                           # for Math::BigInt objects
5501  $x->mantissa();          # return (signed) mantissa as BigInt
5502  $x->exponent();          # return exponent as BigInt
5503  $x->parts();             # return (mantissa,exponent) as BigInt
5504  $x->sparts();            # mantissa and exponent (as integers)
5505  $x->nparts();            # mantissa and exponent (normalised)
5506  $x->eparts();            # mantissa and exponent (engineering notation)
5507  $x->dparts();            # integer and fraction part
5508  $x->fparts();            # numerator and denominator
5509  $x->numerator();         # numerator
5510  $x->denominator();       # denominator
5511
5512  # Conversion methods (do not modify the invocand)
5513
5514  $x->bstr();         # decimal notation, possibly zero padded
5515  $x->bsstr();        # string in scientific notation with integers
5516  $x->bnstr();        # string in normalized notation
5517  $x->bestr();        # string in engineering notation
5518  $x->bdstr();        # string in decimal notation
5519  $x->as_hex();       # as signed hexadecimal string with prefixed 0x
5520  $x->as_bin();       # as signed binary string with prefixed 0b
5521  $x->as_oct();       # as signed octal string with prefixed 0
5522  $x->to_ieee754($format); # to bytes encoded according to IEEE 754-2008
5523
5524  # Other conversion methods
5525
5526  $x->numify();           # return as scalar (might overflow or underflow)
5527
5528=head1 DESCRIPTION
5529
5530Math::BigFloat provides support for arbitrary precision floating point.
5531Overloading is also provided for Perl operators.
5532
5533All operators (including basic math operations) are overloaded if you
5534declare your big floating point numbers as
5535
5536  $x = Math::BigFloat -> new('12_3.456_789_123_456_789E-2');
5537
5538Operations with overloaded operators preserve the arguments, which is
5539exactly what you expect.
5540
5541=head2 Input
5542
5543Input values to these routines may be any scalar number or string that looks
5544like a number. Anything that is accepted by Perl as a literal numeric constant
5545should be accepted by this module.
5546
5547=over
5548
5549=item *
5550
5551Leading and trailing whitespace is ignored.
5552
5553=item *
5554
5555Leading zeros are ignored, except for floating point numbers with a binary
5556exponent, in which case the number is interpreted as an octal floating point
5557number. For example, "01.4p+0" gives 1.5, "00.4p+0" gives 0.5, but "0.4p+0"
5558gives a NaN. And while "0377" gives 255, "0377p0" gives 255.
5559
5560=item *
5561
5562If the string has a "0x" or "0X" prefix, it is interpreted as a hexadecimal
5563number.
5564
5565=item *
5566
5567If the string has a "0o" or "0O" prefix, it is interpreted as an octal number. A
5568floating point literal with a "0" prefix is also interpreted as an octal number.
5569
5570=item *
5571
5572If the string has a "0b" or "0B" prefix, it is interpreted as a binary number.
5573
5574=item *
5575
5576Underline characters are allowed in the same way as they are allowed in literal
5577numerical constants.
5578
5579=item *
5580
5581If the string can not be interpreted, NaN is returned.
5582
5583=item *
5584
5585For hexadecimal, octal, and binary floating point numbers, the exponent must be
5586separated from the significand (mantissa) by the letter "p" or "P", not "e" or
5587"E" as with decimal numbers.
5588
5589=back
5590
5591Some examples of valid string input
5592
5593    Input string                Resulting value
5594
5595    123                         123
5596    1.23e2                      123
5597    12300e-2                    123
5598
5599    67_538_754                  67538754
5600    -4_5_6.7_8_9e+0_1_0         -4567890000000
5601
5602    0x13a                       314
5603    0x13ap0                     314
5604    0x1.3ap+8                   314
5605    0x0.00013ap+24              314
5606    0x13a000p-12                314
5607
5608    0o472                       314
5609    0o1.164p+8                  314
5610    0o0.0001164p+20             314
5611    0o1164000p-10               314
5612
5613    0472                        472     Note!
5614    01.164p+8                   314
5615    00.0001164p+20              314
5616    01164000p-10                314
5617
5618    0b100111010                 314
5619    0b1.0011101p+8              314
5620    0b0.00010011101p+12         314
5621    0b100111010000p-3           314
5622
5623    0x1.921fb5p+1               3.14159262180328369140625e+0
5624    0o1.2677025p1               2.71828174591064453125
5625    01.2677025p1                2.71828174591064453125
5626    0b1.1001p-4                 9.765625e-2
5627
5628=head2 Output
5629
5630Output values are usually Math::BigFloat objects.
5631
5632Boolean operators C<is_zero()>, C<is_one()>, C<is_inf()>, etc. return true or
5633false.
5634
5635Comparison operators C<bcmp()> and C<bacmp()>) return -1, 0, 1, or
5636undef.
5637
5638=head1 METHODS
5639
5640Math::BigFloat supports all methods that Math::BigInt supports, except it
5641calculates non-integer results when possible. Please see L<Math::BigInt> for a
5642full description of each method. Below are just the most important differences:
5643
5644=head2 Configuration methods
5645
5646=over
5647
5648=item accuracy()
5649
5650    $x->accuracy(5);           # local for $x
5651    CLASS->accuracy(5);        # global for all members of CLASS
5652                               # Note: This also applies to new()!
5653
5654    $A = $x->accuracy();       # read out accuracy that affects $x
5655    $A = CLASS->accuracy();    # read out global accuracy
5656
5657Set or get the global or local accuracy, aka how many significant digits the
5658results have. If you set a global accuracy, then this also applies to new()!
5659
5660Warning! The accuracy I<sticks>, e.g. once you created a number under the
5661influence of C<< CLASS->accuracy($A) >>, all results from math operations with
5662that number will also be rounded.
5663
5664In most cases, you should probably round the results explicitly using one of
5665L<Math::BigInt/round()>, L<Math::BigInt/bround()> or L<Math::BigInt/bfround()>
5666or by passing the desired accuracy to the math operation as additional
5667parameter:
5668
5669    my $x = Math::BigInt->new(30000);
5670    my $y = Math::BigInt->new(7);
5671    print scalar $x->copy()->bdiv($y, 2);           # print 4300
5672    print scalar $x->copy()->bdiv($y)->bround(2);   # print 4300
5673
5674=item precision()
5675
5676    $x->precision(-2);        # local for $x, round at the second
5677                              # digit right of the dot
5678    $x->precision(2);         # ditto, round at the second digit
5679                              # left of the dot
5680
5681    CLASS->precision(5);      # Global for all members of CLASS
5682                              # This also applies to new()!
5683    CLASS->precision(-5);     # ditto
5684
5685    $P = CLASS->precision();  # read out global precision
5686    $P = $x->precision();     # read out precision that affects $x
5687
5688Note: You probably want to use L</accuracy()> instead. With L</accuracy()> you
5689set the number of digits each result should have, with L</precision()> you
5690set the place where to round!
5691
5692=back
5693
5694=head2 Constructor methods
5695
5696=over
5697
5698=item from_hex()
5699
5700    $x -> from_hex("0x1.921fb54442d18p+1");
5701    $x = Math::BigFloat -> from_hex("0x1.921fb54442d18p+1");
5702
5703Interpret input as a hexadecimal string.A prefix ("0x", "x", ignoring case) is
5704optional. A single underscore character ("_") may be placed between any two
5705digits. If the input is invalid, a NaN is returned. The exponent is in base 2
5706using decimal digits.
5707
5708If called as an instance method, the value is assigned to the invocand.
5709
5710=item from_oct()
5711
5712    $x -> from_oct("1.3267p-4");
5713    $x = Math::BigFloat -> from_oct("1.3267p-4");
5714
5715Interpret input as an octal string. A single underscore character ("_") may be
5716placed between any two digits. If the input is invalid, a NaN is returned. The
5717exponent is in base 2 using decimal digits.
5718
5719If called as an instance method, the value is assigned to the invocand.
5720
5721=item from_bin()
5722
5723    $x -> from_bin("0b1.1001p-4");
5724    $x = Math::BigFloat -> from_bin("0b1.1001p-4");
5725
5726Interpret input as a hexadecimal string. A prefix ("0b" or "b", ignoring case)
5727is optional. A single underscore character ("_") may be placed between any two
5728digits. If the input is invalid, a NaN is returned. The exponent is in base 2
5729using decimal digits.
5730
5731If called as an instance method, the value is assigned to the invocand.
5732
5733=item from_ieee754()
5734
5735Interpret the input as a value encoded as described in IEEE754-2008.  The input
5736can be given as a byte string, hex string or binary string. The input is
5737assumed to be in big-endian byte-order.
5738
5739        # both $dbl and $mbf are 3.141592...
5740        $bytes = "\x40\x09\x21\xfb\x54\x44\x2d\x18";
5741        $dbl = unpack "d>", $bytes;
5742        $mbf = Math::BigFloat -> from_ieee754($bytes, "binary64");
5743
5744=item bpi()
5745
5746    print Math::BigFloat->bpi(100), "\n";
5747
5748Calculate PI to N digits (including the 3 before the dot). The result is
5749rounded according to the current rounding mode, which defaults to "even".
5750
5751This method was added in v1.87 of Math::BigInt (June 2007).
5752
5753=back
5754
5755=head2 Arithmetic methods
5756
5757=over
5758
5759=item bmuladd()
5760
5761    $x->bmuladd($y,$z);
5762
5763Multiply $x by $y, and then add $z to the result.
5764
5765This method was added in v1.87 of Math::BigInt (June 2007).
5766
5767=item bdiv()
5768
5769    $q = $x->bdiv($y);
5770    ($q, $r) = $x->bdiv($y);
5771
5772In scalar context, divides $x by $y and returns the result to the given or
5773default accuracy/precision. In list context, does floored division
5774(F-division), returning an integer $q and a remainder $r so that $x = $q * $y +
5775$r. The remainer (modulo) is equal to what is returned by C<< $x->bmod($y) >>.
5776
5777=item bmod()
5778
5779    $x->bmod($y);
5780
5781Returns $x modulo $y. When $x is finite, and $y is finite and non-zero, the
5782result is identical to the remainder after floored division (F-division). If,
5783in addition, both $x and $y are integers, the result is identical to the result
5784from Perl's % operator.
5785
5786=item bexp()
5787
5788    $x->bexp($accuracy);            # calculate e ** X
5789
5790Calculates the expression C<e ** $x> where C<e> is Euler's number.
5791
5792This method was added in v1.82 of Math::BigInt (April 2007).
5793
5794=item bnok()
5795
5796    $x->bnok($y);   # x over y (binomial coefficient n over k)
5797
5798Calculates the binomial coefficient n over k, also called the "choose"
5799function. The result is equivalent to:
5800
5801    ( n )      n!
5802    | - |  = -------
5803    ( k )    k!(n-k)!
5804
5805This method was added in v1.84 of Math::BigInt (April 2007).
5806
5807=item bsin()
5808
5809    my $x = Math::BigFloat->new(1);
5810    print $x->bsin(100), "\n";
5811
5812Calculate the sinus of $x, modifying $x in place.
5813
5814This method was added in v1.87 of Math::BigInt (June 2007).
5815
5816=item bcos()
5817
5818    my $x = Math::BigFloat->new(1);
5819    print $x->bcos(100), "\n";
5820
5821Calculate the cosinus of $x, modifying $x in place.
5822
5823This method was added in v1.87 of Math::BigInt (June 2007).
5824
5825=item batan()
5826
5827    my $x = Math::BigFloat->new(1);
5828    print $x->batan(100), "\n";
5829
5830Calculate the arcus tanges of $x, modifying $x in place. See also L</batan2()>.
5831
5832This method was added in v1.87 of Math::BigInt (June 2007).
5833
5834=item batan2()
5835
5836    my $y = Math::BigFloat->new(2);
5837    my $x = Math::BigFloat->new(3);
5838    print $y->batan2($x), "\n";
5839
5840Calculate the arcus tanges of C<$y> divided by C<$x>, modifying $y in place.
5841See also L</batan()>.
5842
5843This method was added in v1.87 of Math::BigInt (June 2007).
5844
5845=item as_float()
5846
5847This method is called when Math::BigFloat encounters an object it doesn't know
5848how to handle. For instance, assume $x is a Math::BigFloat, or subclass
5849thereof, and $y is defined, but not a Math::BigFloat, or subclass thereof. If
5850you do
5851
5852    $x -> badd($y);
5853
5854$y needs to be converted into an object that $x can deal with. This is done by
5855first checking if $y is something that $x might be upgraded to. If that is the
5856case, no further attempts are made. The next is to see if $y supports the
5857method C<as_float()>. The method C<as_float()> is expected to return either an
5858object that has the same class as $x, a subclass thereof, or a string that
5859C<ref($x)-E<gt>new()> can parse to create an object.
5860
5861In Math::BigFloat, C<as_float()> has the same effect as C<copy()>.
5862
5863=item to_ieee754()
5864
5865Encodes the invocand as a byte string in the given format as specified in IEEE
5866754-2008. Note that the encoded value is the nearest possible representation of
5867the value. This value might not be exactly the same as the value in the
5868invocand.
5869
5870    # $x = 3.1415926535897932385
5871    $x = Math::BigFloat -> bpi(30);
5872
5873    $b = $x -> to_ieee754("binary64");  # encode as 8 bytes
5874    $h = unpack "H*", $b;               # "400921fb54442d18"
5875
5876    # 3.141592653589793115997963...
5877    $y = Math::BigFloat -> from_ieee754($h, "binary64");
5878
5879All binary formats in IEEE 754-2008 are accepted. For convenience, som aliases
5880are recognized: "half" for "binary16", "single" for "binary32", "double" for
5881"binary64", "quadruple" for "binary128", "octuple" for "binary256", and
5882"sexdecuple" for "binary512".
5883
5884See also L<https://en.wikipedia.org/wiki/IEEE_754>.
5885
5886=back
5887
5888=head2 ACCURACY AND PRECISION
5889
5890See also: L<Rounding|/Rounding>.
5891
5892Math::BigFloat supports both precision (rounding to a certain place before or
5893after the dot) and accuracy (rounding to a certain number of digits). For a
5894full documentation, examples and tips on these topics please see the large
5895section about rounding in L<Math::BigInt>.
5896
5897Since things like C<sqrt(2)> or C<1 / 3> must presented with a limited
5898accuracy lest a operation consumes all resources, each operation produces
5899no more than the requested number of digits.
5900
5901If there is no global precision or accuracy set, B<and> the operation in
5902question was not called with a requested precision or accuracy, B<and> the
5903input $x has no accuracy or precision set, then a fallback parameter will
5904be used. For historical reasons, it is called C<div_scale> and can be accessed
5905via:
5906
5907    $d = Math::BigFloat->div_scale();       # query
5908    Math::BigFloat->div_scale($n);          # set to $n digits
5909
5910The default value for C<div_scale> is 40.
5911
5912In case the result of one operation has more digits than specified,
5913it is rounded. The rounding mode taken is either the default mode, or the one
5914supplied to the operation after the I<scale>:
5915
5916    $x = Math::BigFloat->new(2);
5917    Math::BigFloat->accuracy(5);              # 5 digits max
5918    $y = $x->copy()->bdiv(3);                 # gives 0.66667
5919    $y = $x->copy()->bdiv(3,6);               # gives 0.666667
5920    $y = $x->copy()->bdiv(3,6,undef,'odd');   # gives 0.666667
5921    Math::BigFloat->round_mode('zero');
5922    $y = $x->copy()->bdiv(3,6);               # will also give 0.666667
5923
5924Note that C<< Math::BigFloat->accuracy() >> and C<< Math::BigFloat->precision() >>
5925set the global variables, and thus B<any> newly created number will be subject
5926to the global rounding B<immediately>. This means that in the examples above, the
5927C<3> as argument to C<bdiv()> will also get an accuracy of B<5>.
5928
5929It is less confusing to either calculate the result fully, and afterwards
5930round it explicitly, or use the additional parameters to the math
5931functions like so:
5932
5933    use Math::BigFloat;
5934    $x = Math::BigFloat->new(2);
5935    $y = $x->copy()->bdiv(3);
5936    print $y->bround(5),"\n";               # gives 0.66667
5937
5938    or
5939
5940    use Math::BigFloat;
5941    $x = Math::BigFloat->new(2);
5942    $y = $x->copy()->bdiv(3,5);             # gives 0.66667
5943    print "$y\n";
5944
5945=head2 Rounding
5946
5947=over
5948
5949=item bfround ( +$scale )
5950
5951Rounds to the $scale'th place left from the '.', counting from the dot.
5952The first digit is numbered 1.
5953
5954=item bfround ( -$scale )
5955
5956Rounds to the $scale'th place right from the '.', counting from the dot.
5957
5958=item bfround ( 0 )
5959
5960Rounds to an integer.
5961
5962=item bround  ( +$scale )
5963
5964Preserves accuracy to $scale digits from the left (aka significant digits) and
5965pads the rest with zeros. If the number is between 1 and -1, the significant
5966digits count from the first non-zero after the '.'
5967
5968=item bround  ( -$scale ) and bround ( 0 )
5969
5970These are effectively no-ops.
5971
5972=back
5973
5974All rounding functions take as a second parameter a rounding mode from one of
5975the following: 'even', 'odd', '+inf', '-inf', 'zero', 'trunc' or 'common'.
5976
5977The default rounding mode is 'even'. By using
5978C<< Math::BigFloat->round_mode($round_mode); >> you can get and set the default
5979mode for subsequent rounding. The usage of C<$Math::BigFloat::$round_mode> is
5980no longer supported.
5981The second parameter to the round functions then overrides the default
5982temporarily.
5983
5984The C<as_number()> function returns a BigInt from a Math::BigFloat. It uses
5985'trunc' as rounding mode to make it equivalent to:
5986
5987    $x = 2.5;
5988    $y = int($x) + 2;
5989
5990You can override this by passing the desired rounding mode as parameter to
5991C<as_number()>:
5992
5993    $x = Math::BigFloat->new(2.5);
5994    $y = $x->as_number('odd');      # $y = 3
5995
5996=head1 NUMERIC LITERALS
5997
5998After C<use Math::BigFloat ':constant'> all numeric literals in the given scope
5999are converted to C<Math::BigFloat> objects. This conversion happens at compile
6000time.
6001
6002For example,
6003
6004    perl -MMath::BigFloat=:constant -le 'print 2e-150'
6005
6006prints the exact value of C<2e-150>. Note that without conversion of constants
6007the expression C<2e-150> is calculated using Perl scalars, which leads to an
6008inaccuracte result.
6009
6010Note that strings are not affected, so that
6011
6012    use Math::BigFloat qw/:constant/;
6013
6014    $y = "1234567890123456789012345678901234567890"
6015            + "123456789123456789";
6016
6017does not give you what you expect. You need an explicit Math::BigFloat->new()
6018around at least one of the operands. You should also quote large constants to
6019prevent loss of precision:
6020
6021    use Math::BigFloat;
6022
6023    $x = Math::BigFloat->new("1234567889123456789123456789123456789");
6024
6025Without the quotes Perl converts the large number to a floating point constant
6026at compile time, and then converts the result to a Math::BigFloat object at
6027runtime, which results in an inaccurate result.
6028
6029=head2 Hexadecimal, octal, and binary floating point literals
6030
6031Perl (and this module) accepts hexadecimal, octal, and binary floating point
6032literals, but use them with care with Perl versions before v5.32.0, because some
6033versions of Perl silently give the wrong result. Below are some examples of
6034different ways to write the number decimal 314.
6035
6036Hexadecimal floating point literals:
6037
6038    0x1.3ap+8         0X1.3AP+8
6039    0x1.3ap8          0X1.3AP8
6040    0x13a0p-4         0X13A0P-4
6041
6042Octal floating point literals (with "0" prefix):
6043
6044    01.164p+8         01.164P+8
6045    01.164p8          01.164P8
6046    011640p-4         011640P-4
6047
6048Octal floating point literals (with "0o" prefix) (requires v5.34.0):
6049
6050    0o1.164p+8        0O1.164P+8
6051    0o1.164p8         0O1.164P8
6052    0o11640p-4        0O11640P-4
6053
6054Binary floating point literals:
6055
6056    0b1.0011101p+8    0B1.0011101P+8
6057    0b1.0011101p8     0B1.0011101P8
6058    0b10011101000p-2  0B10011101000P-2
6059
6060=head2 Math library
6061
6062Math with the numbers is done (by default) by a module called
6063Math::BigInt::Calc. This is equivalent to saying:
6064
6065    use Math::BigFloat lib => "Calc";
6066
6067You can change this by using:
6068
6069    use Math::BigFloat lib => "GMP";
6070
6071B<Note>: General purpose packages should not be explicit about the library to
6072use; let the script author decide which is best.
6073
6074Note: The keyword 'lib' will warn when the requested library could not be
6075loaded. To suppress the warning use 'try' instead:
6076
6077    use Math::BigFloat try => "GMP";
6078
6079If your script works with huge numbers and Calc is too slow for them, you can
6080also for the loading of one of these libraries and if none of them can be used,
6081the code will die:
6082
6083    use Math::BigFloat only => "GMP,Pari";
6084
6085The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar,
6086and when this also fails, revert to Math::BigInt::Calc:
6087
6088    use Math::BigFloat lib => "Foo,Math::BigInt::Bar";
6089
6090See the respective low-level library documentation for further details.
6091
6092See L<Math::BigInt> for more details about using a different low-level library.
6093
6094=head2 Using Math::BigInt::Lite
6095
6096For backwards compatibility reasons it is still possible to
6097request a different storage class for use with Math::BigFloat:
6098
6099    use Math::BigFloat with => 'Math::BigInt::Lite';
6100
6101However, this request is ignored, as the current code now uses the low-level
6102math library for directly storing the number parts.
6103
6104=head1 EXPORTS
6105
6106C<Math::BigFloat> exports nothing by default, but can export the C<bpi()> method:
6107
6108    use Math::BigFloat qw/bpi/;
6109
6110    print bpi(10), "\n";
6111
6112=head1 CAVEATS
6113
6114Do not try to be clever to insert some operations in between switching
6115libraries:
6116
6117    require Math::BigFloat;
6118    my $matter = Math::BigFloat->bone() + 4;    # load BigInt and Calc
6119    Math::BigFloat->import( lib => 'Pari' );    # load Pari, too
6120    my $anti_matter = Math::BigFloat->bone()+4; # now use Pari
6121
6122This will create objects with numbers stored in two different backend libraries,
6123and B<VERY BAD THINGS> will happen when you use these together:
6124
6125    my $flash_and_bang = $matter + $anti_matter;    # Don't do this!
6126
6127=over
6128
6129=item stringify, bstr()
6130
6131Both stringify and bstr() now drop the leading '+'. The old code would return
6132'+1.23', the new returns '1.23'. See the documentation in L<Math::BigInt> for
6133reasoning and details.
6134
6135=item brsft()
6136
6137The following will probably not print what you expect:
6138
6139    my $c = Math::BigFloat->new('3.14159');
6140    print $c->brsft(3,10),"\n";     # prints 0.00314153.1415
6141
6142It prints both quotient and remainder, since print calls C<brsft()> in list
6143context. Also, C<< $c->brsft() >> will modify $c, so be careful.
6144You probably want to use
6145
6146    print scalar $c->copy()->brsft(3,10),"\n";
6147    # or if you really want to modify $c
6148    print scalar $c->brsft(3,10),"\n";
6149
6150instead.
6151
6152=item Modifying and =
6153
6154Beware of:
6155
6156    $x = Math::BigFloat->new(5);
6157    $y = $x;
6158
6159It will not do what you think, e.g. making a copy of $x. Instead it just makes
6160a second reference to the B<same> object and stores it in $y. Thus anything
6161that modifies $x will modify $y (except overloaded math operators), and vice
6162versa. See L<Math::BigInt> for details and how to avoid that.
6163
6164=item precision() vs. accuracy()
6165
6166A common pitfall is to use L</precision()> when you want to round a result to
6167a certain number of digits:
6168
6169    use Math::BigFloat;
6170
6171    Math::BigFloat->precision(4);           # does not do what you
6172                                            # think it does
6173    my $x = Math::BigFloat->new(12345);     # rounds $x to "12000"!
6174    print "$x\n";                           # print "12000"
6175    my $y = Math::BigFloat->new(3);         # rounds $y to "0"!
6176    print "$y\n";                           # print "0"
6177    $z = $x / $y;                           # 12000 / 0 => NaN!
6178    print "$z\n";
6179    print $z->precision(),"\n";             # 4
6180
6181Replacing L</precision()> with L</accuracy()> is probably not what you want, either:
6182
6183    use Math::BigFloat;
6184
6185    Math::BigFloat->accuracy(4);          # enables global rounding:
6186    my $x = Math::BigFloat->new(123456);  # rounded immediately
6187                                          #   to "12350"
6188    print "$x\n";                         # print "123500"
6189    my $y = Math::BigFloat->new(3);       # rounded to "3
6190    print "$y\n";                         # print "3"
6191    print $z = $x->copy()->bdiv($y),"\n"; # 41170
6192    print $z->accuracy(),"\n";            # 4
6193
6194What you want to use instead is:
6195
6196    use Math::BigFloat;
6197
6198    my $x = Math::BigFloat->new(123456);    # no rounding
6199    print "$x\n";                           # print "123456"
6200    my $y = Math::BigFloat->new(3);         # no rounding
6201    print "$y\n";                           # print "3"
6202    print $z = $x->copy()->bdiv($y,4),"\n"; # 41150
6203    print $z->accuracy(),"\n";              # undef
6204
6205In addition to computing what you expected, the last example also does B<not>
6206"taint" the result with an accuracy or precision setting, which would
6207influence any further operation.
6208
6209=back
6210
6211=head1 BUGS
6212
6213Please report any bugs or feature requests to
6214C<bug-math-bigint at rt.cpan.org>, or through the web interface at
6215L<https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt> (requires login).
6216We will be notified, and then you'll automatically be notified of progress on
6217your bug as I make changes.
6218
6219=head1 SUPPORT
6220
6221You can find documentation for this module with the perldoc command.
6222
6223    perldoc Math::BigFloat
6224
6225You can also look for information at:
6226
6227=over 4
6228
6229=item * GitHub
6230
6231L<https://github.com/pjacklam/p5-Math-BigInt>
6232
6233=item * RT: CPAN's request tracker
6234
6235L<https://rt.cpan.org/Dist/Display.html?Name=Math-BigInt>
6236
6237=item * MetaCPAN
6238
6239L<https://metacpan.org/release/Math-BigInt>
6240
6241=item * CPAN Testers Matrix
6242
6243L<http://matrix.cpantesters.org/?dist=Math-BigInt>
6244
6245=item * CPAN Ratings
6246
6247L<https://cpanratings.perl.org/dist/Math-BigInt>
6248
6249=item * The Bignum mailing list
6250
6251=over 4
6252
6253=item * Post to mailing list
6254
6255C<bignum at lists.scsys.co.uk>
6256
6257=item * View mailing list
6258
6259L<http://lists.scsys.co.uk/pipermail/bignum/>
6260
6261=item * Subscribe/Unsubscribe
6262
6263L<http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/bignum>
6264
6265=back
6266
6267=back
6268
6269=head1 LICENSE
6270
6271This program is free software; you may redistribute it and/or modify it under
6272the same terms as Perl itself.
6273
6274=head1 SEE ALSO
6275
6276L<Math::BigInt> and L<Math::BigInt> as well as the backends
6277L<Math::BigInt::FastCalc>, L<Math::BigInt::GMP>, and L<Math::BigInt::Pari>.
6278
6279The pragmas L<bignum>, L<bigint> and L<bigrat>.
6280
6281=head1 AUTHORS
6282
6283=over 4
6284
6285=item *
6286
6287Mark Biggar, overloaded interface by Ilya Zakharevich, 1996-2001.
6288
6289=item *
6290
6291Completely rewritten by Tels L<http://bloodgate.com> in 2001-2008.
6292
6293=item *
6294
6295Florian Ragwitz E<lt>flora@cpan.orgE<gt>, 2010.
6296
6297=item *
6298
6299Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2011-.
6300
6301=back
6302
6303=cut
6304