File Coverage

blib/lib/Math/BigInt.pm
Criterion Covered Total %
statement 1550 2179 71.1
branch 1215 2038 59.6
condition 632 1044 60.5
subroutine 181 235 77.0
pod 135 136 99.2
total 3713 5632 65.9


line stmt bran cond sub pod time code
1             # -*- coding: utf-8-unix -*-
2              
3             package Math::BigInt;
4              
5             #
6             # "Mike had an infinite amount to do and a negative amount of time in which
7             # to do it." - Before and After
8             #
9              
10             # The following hash values are used:
11             # value: unsigned int with actual value (as a Math::BigInt::Calc or similar)
12             # sign : +, -, NaN, +inf, -inf
13             # _a : accuracy
14             # _p : precision
15              
16             # Remember not to take shortcuts ala $xs = $x->{value}; $LIB->foo($xs); since
17             # underlying lib might change the reference!
18              
19 51     51   2000464 use 5.006001;
  51         443  
20 51     51   290 use strict;
  51         103  
  51         1182  
21 51     51   265 use warnings;
  51         111  
  51         2113  
22              
23 51     51   382 use Carp qw< carp croak >;
  51         138  
  51         3184  
24 51     51   409 use Scalar::Util qw< blessed refaddr >;
  51         129  
  51         92779  
25              
26             our $VERSION = '1.999841';
27             $VERSION =~ tr/_//d;
28              
29             require Exporter;
30             our @ISA = qw(Exporter);
31             our @EXPORT_OK = qw(objectify bgcd blcm);
32              
33             # Inside overload, the first arg is always an object. If the original code had
34             # it reversed (like $x = 2 * $y), then the third parameter is true.
35             # In some cases (like add, $x = $x + 2 is the same as $x = 2 + $x) this makes
36             # no difference, but in some cases it does.
37              
38             # For overloaded ops with only one argument we simple use $_[0]->copy() to
39             # preserve the argument.
40              
41             # Thus inheritance of overload operators becomes possible and transparent for
42             # our subclasses without the need to repeat the entire overload section there.
43              
44             use overload
45              
46             # overload key: with_assign
47              
48 309     309   1114 '+' => sub { $_[0] -> copy() -> badd($_[1]); },
49              
50 356     356   2131 '-' => sub { my $c = $_[0] -> copy();
51 356 100       1019 $_[2] ? $c -> bneg() -> badd($_[1])
52             : $c -> bsub($_[1]); },
53              
54 960     960   5143 '*' => sub { $_[0] -> copy() -> bmul($_[1]); },
55              
56 341 100   341   1581 '/' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bdiv($_[0])
57             : $_[0] -> copy() -> bdiv($_[1]); },
58              
59 353 100   353   4439 '%' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bmod($_[0])
60             : $_[0] -> copy() -> bmod($_[1]); },
61              
62 439 100   439   6753 '**' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bpow($_[0])
63             : $_[0] -> copy() -> bpow($_[1]); },
64              
65 20 50   20   295 '<<' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bblsft($_[0])
66             : $_[0] -> copy() -> bblsft($_[1]); },
67              
68 20 50   20   290 '>>' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bbrsft($_[0])
69             : $_[0] -> copy() -> bbrsft($_[1]); },
70              
71             # overload key: assign
72              
73 27     27   1405 '+=' => sub { $_[0] -> badd($_[1]); },
74              
75 29     29   1324 '-=' => sub { $_[0] -> bsub($_[1]); },
76              
77 17     17   251 '*=' => sub { $_[0] -> bmul($_[1]); },
78              
79 14     14   198 '/=' => sub { scalar $_[0] -> bdiv($_[1]); },
80              
81 17     17   228 '%=' => sub { $_[0] -> bmod($_[1]); },
82              
83 6     6   107 '**=' => sub { $_[0] -> bpow($_[1]); },
84              
85 3     3   50 '<<=' => sub { $_[0] -> bblsft($_[1]); },
86              
87 3     3   25 '>>=' => sub { $_[0] -> bbrsft($_[1]); },
88              
89             # 'x=' => sub { },
90              
91             # '.=' => sub { },
92              
93             # overload key: num_comparison
94              
95 318 50   318   1060 '<' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> blt($_[0])
96             : $_[0] -> blt($_[1]); },
97              
98 621 100   621   3684 '<=' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> ble($_[0])
99             : $_[0] -> ble($_[1]); },
100              
101 506 50   506   1841 '>' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bgt($_[0])
102             : $_[0] -> bgt($_[1]); },
103              
104 140 50   140   5720 '>=' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bge($_[0])
105             : $_[0] -> bge($_[1]); },
106              
107 241     241   92772 '==' => sub { $_[0] -> beq($_[1]); },
108              
109 9     9   524 '!=' => sub { $_[0] -> bne($_[1]); },
110              
111             # overload key: 3way_comparison
112              
113 0     0   0 '<=>' => sub { my $cmp = $_[0] -> bcmp($_[1]);
114 0 0 0     0 defined($cmp) && $_[2] ? -$cmp : $cmp; },
115              
116 7947 50   7947   2027233 'cmp' => sub { $_[2] ? "$_[1]" cmp $_[0] -> bstr()
117             : $_[0] -> bstr() cmp "$_[1]"; },
118              
119             # overload key: str_comparison
120              
121             # 'lt' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrlt($_[0])
122             # : $_[0] -> bstrlt($_[1]); },
123             #
124             # 'le' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrle($_[0])
125             # : $_[0] -> bstrle($_[1]); },
126             #
127             # 'gt' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrgt($_[0])
128             # : $_[0] -> bstrgt($_[1]); },
129             #
130             # 'ge' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrge($_[0])
131             # : $_[0] -> bstrge($_[1]); },
132             #
133             # 'eq' => sub { $_[0] -> bstreq($_[1]); },
134             #
135             # 'ne' => sub { $_[0] -> bstrne($_[1]); },
136              
137             # overload key: binary
138              
139 140 100   140   2049 '&' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> band($_[0])
140             : $_[0] -> copy() -> band($_[1]); },
141              
142 4     4   92 '&=' => sub { $_[0] -> band($_[1]); },
143              
144 201 100   201   3938 '|' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bior($_[0])
145             : $_[0] -> copy() -> bior($_[1]); },
146              
147 4     4   74 '|=' => sub { $_[0] -> bior($_[1]); },
148              
149 199 100   199   2714 '^' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bxor($_[0])
150             : $_[0] -> copy() -> bxor($_[1]); },
151              
152 4     4   72 '^=' => sub { $_[0] -> bxor($_[1]); },
153              
154             # '&.' => sub { },
155              
156             # '&.=' => sub { },
157              
158             # '|.' => sub { },
159              
160             # '|.=' => sub { },
161              
162             # '^.' => sub { },
163              
164             # '^.=' => sub { },
165              
166             # overload key: unary
167              
168 285     285   837 'neg' => sub { $_[0] -> copy() -> bneg(); },
169              
170             # '!' => sub { },
171              
172 0     0   0 '~' => sub { $_[0] -> copy() -> bnot(); },
173              
174             # '~.' => sub { },
175              
176             # overload key: mutators
177              
178 23     23   210 '++' => sub { $_[0] -> binc() },
179              
180 3     3   47 '--' => sub { $_[0] -> bdec() },
181              
182             # overload key: func
183              
184 0 0   0   0 'atan2' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> batan2($_[0])
185             : $_[0] -> copy() -> batan2($_[1]); },
186              
187 0     0   0 'cos' => sub { $_[0] -> copy() -> bcos(); },
188              
189 0     0   0 'sin' => sub { $_[0] -> copy() -> bsin(); },
190              
191 0     0   0 'exp' => sub { $_[0] -> copy() -> bexp($_[1]); },
192              
193 3     3   63 'abs' => sub { $_[0] -> copy() -> babs(); },
194              
195 30     30   499 'log' => sub { $_[0] -> copy() -> blog(); },
196              
197 1     1   4 'sqrt' => sub { $_[0] -> copy() -> bsqrt(); },
198              
199 6     6   28 'int' => sub { $_[0] -> copy() -> bint(); },
200              
201             # overload key: conversion
202              
203 6 100   6   96 'bool' => sub { $_[0] -> is_zero() ? '' : 1; },
204              
205 1855     1855   5418 '""' => sub { $_[0] -> bstr(); },
206              
207 51     51   140 '0+' => sub { $_[0] -> numify(); },
208              
209 0     0   0 '=' => sub { $_[0] -> copy(); },
210              
211 51     51   53728 ;
  51         43697  
  51         3933  
212              
213             ##############################################################################
214             # global constants, flags and accessory
215              
216             # These vars are public, but their direct usage is not recommended, use the
217             # accessor methods instead
218              
219             # $round_mode is 'even', 'odd', '+inf', '-inf', 'zero', 'trunc', or 'common'.
220             our $round_mode = 'even';
221             our $accuracy = undef;
222             our $precision = undef;
223             our $div_scale = 40;
224             our $upgrade = undef; # default is no upgrade
225             our $downgrade = undef; # default is no downgrade
226              
227             # These are internally, and not to be used from the outside at all
228              
229             our $_trap_nan = 0; # are NaNs ok? set w/ config()
230             our $_trap_inf = 0; # are infs ok? set w/ config()
231              
232             my $nan = 'NaN'; # constants for easier life
233              
234             # Module to do the low level math.
235              
236             my $DEFAULT_LIB = 'Math::BigInt::Calc';
237             my $LIB;
238              
239             # Has import() been called yet? Needed to make "require" work.
240              
241             my $IMPORT = 0;
242              
243             ##############################################################################
244             # the old code had $rnd_mode, so we need to support it, too
245              
246             our $rnd_mode = 'even';
247              
248             sub TIESCALAR {
249 51     51   195 my ($class) = @_;
250 51         268 bless \$round_mode, $class;
251             }
252              
253             sub FETCH {
254 3     3   85 return $round_mode;
255             }
256              
257             sub STORE {
258 52     52   889 $rnd_mode = $_[0]->round_mode($_[1]);
259             }
260              
261             BEGIN {
262             # tie to enable $rnd_mode to work transparently
263 51     51   40834 tie $rnd_mode, 'Math::BigInt';
264              
265             # set up some handy alias names
266 51         400 *is_pos = \&is_positive;
267 51         426 *is_neg = \&is_negative;
268 51         9730 *as_number = \&as_int;
269             }
270              
271             ###############################################################################
272             # Configuration methods
273             ###############################################################################
274              
275             sub round_mode {
276 410     410 1 12269 my $self = shift;
277 410   50     2105 my $class = ref($self) || $self || __PACKAGE__;
278              
279 410 100       1078 if (@_) { # setter
280 367         647 my $m = shift;
281 367 50       817 croak("The value for 'round_mode' must be defined")
282             unless defined $m;
283 367 100       2652 croak("Unknown round mode '$m'")
284             unless $m =~ /^(even|odd|\+inf|\-inf|zero|trunc|common)$/;
285 51     51   426 no strict 'refs';
  51         106  
  51         3055  
286 363         601 ${"${class}::round_mode"} = $m;
  363         4207  
287             }
288              
289             else { # getter
290 51     51   310 no strict 'refs';
  51         97  
  51         4035  
291 43         72 my $m = ${"${class}::round_mode"};
  43         222  
292 43 100       247 defined($m) ? $m : $round_mode;
293             }
294             }
295              
296             sub upgrade {
297 51     51   325 no strict 'refs';
  51         109  
  51         6541  
298             # make Class->upgrade() work
299 3332     3332 1 7384 my $self = shift;
300 3332   50     10883 my $class = ref($self) || $self || __PACKAGE__;
301              
302             # need to set new value?
303 3332 100       6927 if (@_ > 0) {
304 2023         2917 return ${"${class}::upgrade"} = $_[0];
  2023         5824  
305             }
306 1309         1852 ${"${class}::upgrade"};
  1309         4397  
307             }
308              
309             sub downgrade {
310 51     51   370 no strict 'refs';
  51         116  
  51         10370  
311             # make Class->downgrade() work
312 3140     3140 1 10365 my $self = shift;
313 3140   50     9732 my $class = ref($self) || $self || __PACKAGE__;
314             # need to set new value?
315 3140 100       6051 if (@_ > 0) {
316 2093         2970 return ${"${class}::downgrade"} = $_[0];
  2093         5357  
317             }
318 1047         1554 ${"${class}::downgrade"};
  1047         2978  
319             }
320              
321             sub div_scale {
322 946     946 1 4801 my $self = shift;
323 946   50     3874 my $class = ref($self) || $self || __PACKAGE__;
324              
325 946 100       2370 if (@_) { # setter
326 15         27 my $ds = shift;
327 15 50       46 croak("The value for 'div_scale' must be defined") unless defined $ds;
328 15 50       50 croak("The value for 'div_scale' must be positive") unless $ds > 0;
329 15 50       65 $ds = $ds -> numify() if defined(blessed($ds));
330 51     51   448 no strict 'refs';
  51         208  
  51         3196  
331 15         27 ${"${class}::div_scale"} = $ds;
  15         82  
332             }
333              
334             else { # getter
335 51     51   340 no strict 'refs';
  51         156  
  51         5184  
336 931         1706 my $ds = ${"${class}::div_scale"};
  931         2464  
337 931 100       2997 defined($ds) ? $ds : $div_scale;
338             }
339             }
340              
341             sub accuracy {
342             # $x->accuracy($a); ref($x) $a
343             # $x->accuracy(); ref($x)
344             # Class->accuracy(); class
345             # Class->accuracy($a); class $a
346              
347 8021     8021 1 68998 my $x = shift;
348 8021   50     27850 my $class = ref($x) || $x || __PACKAGE__;
349              
350 51     51   357 no strict 'refs';
  51         138  
  51         18079  
351 8021 100       18246 if (@_ > 0) {
352 526         878 my $a = shift;
353 526 100       1158 if (defined $a) {
354 433 0       973 $a = $a -> can('numify') ? $a -> numify() : 0 + "$a" if ref($a);
    50          
355             # also croak on non-numerical
356 433 50       2540 croak "accuracy must be a number, not '$a'"
357             unless $a =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
358 433 50       1122 croak "accuracy must be an integer, not '$a'"
359             if $a != int $a;
360 433 50       941 croak "accuracy must be greater than zero, not '$a'"
361             if $a <= 0;
362             }
363              
364 526 100       1197 if (ref($x)) {
365             # Set instance variable.
366 442 100       1568 $x = $x->bround($a) if defined $a;
367 442         947 $x->{_a} = $a; # set/overwrite, even if not rounded
368 442         772 $x->{_p} = undef; # clear P
369             # Why return class variable here? Fixme!
370 442 100       1002 $a = ${"${class}::accuracy"} unless defined $a;
  53         169  
371             } else {
372             # Set class variable.
373 84         122 ${"${class}::accuracy"} = $a; # set global A
  84         324  
374 84         143 ${"${class}::precision"} = undef; # clear global P
  84         209  
375             }
376              
377 526         2885 return $a; # shortcut
378             }
379              
380             # Return instance variable.
381 7495 100       15200 return $x->{_a} if ref($x);
382              
383             # Return class variable.
384 7409         9758 return ${"${class}::accuracy"};
  7409         26215  
385             }
386              
387             sub precision {
388             # $x->precision($p); ref($x) $p
389             # $x->precision(); ref($x)
390             # Class->precision(); class
391             # Class->precision($p); class $p
392              
393 7795     7795 1 23578 my $x = shift;
394 7795   50     26196 my $class = ref($x) || $x || __PACKAGE__;
395              
396 51     51   400 no strict 'refs';
  51         174  
  51         16697  
397 7795 100       17169 if (@_ > 0) {
398 293         565 my $p = shift;
399 293 100       673 if (defined $p) {
400 208 0       481 $p = $p -> can('numify') ? $p -> numify() : 0 + "$p" if ref($p);
    50          
401 208 50       1305 croak "precision must be a number, not '$p'"
402             unless $p =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
403 208 50       616 croak "precision must be an integer, not '$p'"
404             if $p != int $p;
405             }
406              
407 293 100       687 if (ref($x)) {
408             # Set instance variable.
409 207 100       751 $x = $x->bfround($p) if defined $p;
410 207         391 $x->{_p} = $p; # set/overwrite, even if not rounded
411 207         341 $x->{_a} = undef; # clear A
412             # Why return class variable here? Fixme!
413 207 100       475 $p = ${"${class}::precision"} unless defined $p;
  49         160  
414             } else {
415             # Set class variable.
416 86         120 ${"${class}::precision"} = $p; # set global P
  86         318  
417 86         134 ${"${class}::accuracy"} = undef; # clear global A
  86         214  
418             }
419              
420 293         2177 return $p; # shortcut
421             }
422              
423             # Return instance variable.
424 7502 100       14252 return $x->{_p} if ref($x);
425              
426             # Return class variable.
427 7415         9798 return ${"${class}::precision"};
  7415         22309  
428             }
429              
430             sub config {
431             # return (or set) configuration data.
432 286   50 286 1 43652 my $class = shift || __PACKAGE__;
433              
434 51     51   429 no strict 'refs';
  51         394  
  51         24353  
435 286 100 100     2367 if (@_ > 1 || (@_ == 1 && (ref($_[0]) eq 'HASH'))) {
      100        
436             # try to set given options as arguments from hash
437              
438 30         51 my $args = $_[0];
439 30 100       85 if (ref($args) ne 'HASH') {
440 28         79 $args = { @_ };
441             }
442             # these values can be "set"
443 30         53 my $set_args = {};
444 30         60 foreach my $key (qw/
445             accuracy precision
446             round_mode div_scale
447             upgrade downgrade
448             trap_inf trap_nan
449             /)
450             {
451 240 100       428 $set_args->{$key} = $args->{$key} if exists $args->{$key};
452 240         370 delete $args->{$key};
453             }
454 30 100       96 if (keys %$args > 0) {
455 2         369 croak("Illegal key(s) '", join("', '", keys %$args),
456             "' passed to $class\->config()");
457             }
458 28         71 foreach my $key (keys %$set_args) {
459 28 100       127 if ($key =~ /^trap_(inf|nan)\z/) {
460 16 100       73 ${"${class}::_trap_$1"} = ($set_args->{"trap_$1"} ? 1 : 0);
  16         60  
461 16         55 next;
462             }
463             # use a call instead of just setting the $variable to check argument
464 12         56 $class->$key($set_args->{$key});
465             }
466             }
467              
468             # now return actual configuration
469              
470             my $cfg = {
471             lib => $LIB,
472 284         1212 lib_version => ${"${LIB}::VERSION"},
473             class => $class,
474 284         779 trap_nan => ${"${class}::_trap_nan"},
475 284         711 trap_inf => ${"${class}::_trap_inf"},
476 284         584 version => ${"${class}::VERSION"},
  284         1659  
477             };
478 284         713 foreach my $key (qw/
479             accuracy precision
480             round_mode div_scale
481             upgrade downgrade
482             /)
483             {
484 1704         2252 $cfg->{$key} = ${"${class}::$key"};
  1704         4944  
485             }
486 284 100 100     1329 if (@_ == 1 && (ref($_[0]) ne 'HASH')) {
487             # calls of the style config('lib') return just this value
488 230         1617 return $cfg->{$_[0]};
489             }
490 54         183 $cfg;
491             }
492              
493             sub _scale_a {
494             # select accuracy parameter based on precedence,
495             # used by bround() and bfround(), may return undef for scale (means no op)
496 67505     67505   122188 my ($x, $scale, $mode) = @_;
497              
498 67505 100       130363 $scale = $x->{_a} unless defined $scale;
499              
500 51     51   430 no strict 'refs';
  51         143  
  51         8967  
501 67505         99949 my $class = ref($x);
502              
503 67505 100       116913 $scale = ${ $class . '::accuracy' } unless defined $scale;
  3891         10742  
504 67505 100       113638 $mode = ${ $class . '::round_mode' } unless defined $mode;
  12203         33253  
505              
506 67505 100       117729 if (defined $scale) {
507 63614 50       108667 $scale = $scale->can('numify') ? $scale->numify()
    100          
508             : "$scale" if ref($scale);
509 63614         85091 $scale = int($scale);
510             }
511              
512 67505         186654 ($scale, $mode);
513             }
514              
515             sub _scale_p {
516             # select precision parameter based on precedence,
517             # used by bround() and bfround(), may return undef for scale (means no op)
518 936     936   2248 my ($x, $scale, $mode) = @_;
519              
520 936 100       1932 $scale = $x->{_p} unless defined $scale;
521              
522 51     51   395 no strict 'refs';
  51         135  
  51         158572  
523 936         1512 my $class = ref($x);
524              
525 936 100       1742 $scale = ${ $class . '::precision' } unless defined $scale;
  4         15  
526 936 100       1852 $mode = ${ $class . '::round_mode' } unless defined $mode;
  716         2120  
527              
528 936 100       1996 if (defined $scale) {
529 932 0       1768 $scale = $scale->can('numify') ? $scale->numify()
    50          
530             : "$scale" if ref($scale);
531 932         1387 $scale = int($scale);
532             }
533              
534 936         3162 ($scale, $mode);
535             }
536              
537             ###############################################################################
538             # Constructor methods
539             ###############################################################################
540              
541             sub new {
542             # Create a new Math::BigInt object from a string or another Math::BigInt
543             # object. See hash keys documented at top.
544              
545             # The argument could be an object, so avoid ||, && etc. on it. This would
546             # cause costly overloaded code to be called. The only allowed ops are ref()
547             # and defined.
548              
549 19924     19924 1 5246593 my $self = shift;
550 19924         35024 my $selfref = ref $self;
551 19924   33     67636 my $class = $selfref || $self;
552              
553             # Make "require" work.
554              
555 19924 100       44127 $class -> import() if $IMPORT == 0;
556              
557             # Calling new() with no input arguments has been discouraged for more than
558             # 10 years, but people apparently still use it, so we still support it.
559              
560 19924 100       42645 return $class -> bzero() unless @_;
561              
562 19916         41222 my ($wanted, @r) = @_;
563              
564 19916 50       40879 if (!defined($wanted)) {
565             #carp("Use of uninitialized value in new()")
566             # if warnings::enabled("uninitialized");
567 0         0 return $class -> bzero(@r);
568             }
569              
570 19916 100 100     70442 if (!ref($wanted) && $wanted eq "") {
571             #carp(q|Argument "" isn't numeric in new()|)
572             # if warnings::enabled("numeric");
573             #return $class -> bzero(@r);
574 4         21 return $class -> bnan(@r);
575             }
576              
577             # Initialize a new object.
578              
579 19912         44734 $self = bless {}, $class;
580              
581             # Math::BigInt or subclass
582              
583 19912 100 100     65201 if (defined(blessed($wanted)) && $wanted -> isa(__PACKAGE__)) {
584              
585             # Don't copy the accuracy and precision, because a new object should get
586             # them from the global configuration.
587              
588 5         35 $self -> {sign} = $wanted -> {sign};
589 5         29 $self -> {value} = $LIB -> _copy($wanted -> {value});
590 5 50 66     36 $self = $self->round(@r)
      66        
591             unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
592 5         40 return $self;
593             }
594              
595             # Shortcut for non-zero scalar integers with no non-zero exponent.
596              
597 19907 100       97379 if ($wanted =~
598             / ^
599             ( [+-]? ) # optional sign
600             ( [1-9] [0-9]* ) # non-zero significand
601             ( \.0* )? # ... with optional zero fraction
602             ( [Ee] [+-]? 0+ )? # optional zero exponent
603             \z
604             /x)
605             {
606 12829         28874 my $sgn = $1;
607 12829         22430 my $abs = $2;
608 12829   100     46384 $self->{sign} = $sgn || '+';
609 12829         41309 $self->{value} = $LIB->_new($abs);
610 12829         34060 $self = $self->round(@r);
611 12829         114244 return $self;
612             }
613              
614             # Handle Infs.
615              
616 7078 100       21141 if ($wanted =~ / ^
617             \s*
618             ( [+-]? )
619             inf (?: inity )?
620             \s*
621             \z
622             /ix)
623             {
624 1755   100     6660 my $sgn = $1 || '+';
625 1755         5375 return $class -> binf($sgn, @r);
626             }
627              
628             # Handle explicit NaNs (not the ones returned due to invalid input).
629              
630 5323 100       12679 if ($wanted =~ / ^
631             \s*
632             ( [+-]? )
633             nan
634             \s*
635             \z
636             /ix)
637             {
638 391         1448 return $class -> bnan(@r);
639             }
640              
641 4932         7559 my @parts;
642              
643 4932 100 100     49890 if (
      33        
      66        
      100        
      66        
      100        
      33        
      66        
644             # Handle hexadecimal numbers. We auto-detect hexadecimal numbers if they
645             # have a "0x", "0X", "x", or "X" prefix, cf. CORE::oct().
646              
647             $wanted =~ /^\s*[+-]?0?[Xx]/ and
648             @parts = $class -> _hex_str_to_flt_lib_parts($wanted)
649              
650             or
651              
652             # Handle octal numbers. We auto-detect octal numbers if they have a
653             # "0o", "0O", "o", "O" prefix, cf. CORE::oct().
654              
655             $wanted =~ /^\s*[+-]?0?[Oo]/ and
656             @parts = $class -> _oct_str_to_flt_lib_parts($wanted)
657              
658             or
659              
660             # Handle binary numbers. We auto-detect binary numbers if they have a
661             # "0b", "0B", "b", or "B" prefix, cf. CORE::oct().
662              
663             $wanted =~ /^\s*[+-]?0?[Bb]/ and
664             @parts = $class -> _bin_str_to_flt_lib_parts($wanted)
665              
666             or
667              
668             # At this point, what is left are decimal numbers that aren't handled
669             # above and octal floating point numbers that don't have any of the
670             # "0o", "0O", "o", or "O" prefixes. First see if it is a decimal number.
671              
672             @parts = $class -> _dec_str_to_flt_lib_parts($wanted)
673             or
674              
675             # See if it is an octal floating point number. The extra check is
676             # included because _oct_str_to_flt_lib_parts() accepts octal numbers
677             # that don't have a prefix (this is needed to make it work with, e.g.,
678             # from_oct() that don't require a prefix). However, Perl requires a
679             # prefix for octal floating point literals. For example, "1p+0" is not
680             # valid, but "01p+0" and "0__1p+0" are.
681              
682             $wanted =~ /^\s*[+-]?0_*\d/ and
683             @parts = $class -> _oct_str_to_flt_lib_parts($wanted))
684             {
685             # The value is an integer iff the exponent is non-negative.
686              
687 4293 100       10427 if ($parts[2] eq '+') {
688 4252         10776 $self -> {sign} = $parts[0];
689 4252         13786 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
690 4252 100 100     18015 $self = $self->round(@r)
      66        
691             unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
692 4252         37239 return $self;
693             }
694              
695             # The value is not an integer, so upgrade if upgrading is enabled.
696              
697 41 100       178 return $upgrade -> new($wanted, @r) if defined $upgrade;
698             }
699              
700             # If we get here, the value is neither a valid decimal, binary, octal, or
701             # hexadecimal number. It is not explicit an Inf or a NaN either.
702              
703 670         1914 return $class -> bnan(@r);
704             }
705              
706             # Create a Math::BigInt from a decimal string. This is an equivalent to
707             # from_hex(), from_oct(), and from_bin(). It is like new() except that it does
708             # not accept anything but a string representing a finite decimal number.
709              
710             sub from_dec {
711 0     0 1 0 my $self = shift;
712 0         0 my $selfref = ref $self;
713 0   0     0 my $class = $selfref || $self;
714              
715             # Don't modify constant (read-only) objects.
716              
717 0 0 0     0 return $self if $selfref && $self->modify('from_dec');
718              
719 0         0 my $str = shift;
720 0         0 my @r = @_;
721              
722             # If called as a class method, initialize a new object.
723              
724 0 0       0 $self = $class -> bzero(@r) unless $selfref;
725              
726 0 0       0 if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
727              
728             # The value is an integer iff the exponent is non-negative.
729              
730 0 0       0 if ($parts[2] eq '+') {
731 0         0 $self -> {sign} = $parts[0];
732 0         0 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
733 0         0 return $self -> round(@r);
734             }
735              
736             # The value is not an integer, so upgrade if upgrading is enabled.
737              
738 0 0       0 return $upgrade -> new($str, @r) if defined $upgrade;
739             }
740              
741 0         0 return $self -> bnan(@r);
742             }
743              
744             # Create a Math::BigInt from a hexadecimal string.
745              
746             sub from_hex {
747 2     2 1 671 my $self = shift;
748 2         6 my $selfref = ref $self;
749 2   33     10 my $class = $selfref || $self;
750              
751             # Don't modify constant (read-only) objects.
752              
753 2 50 33     13 return $self if $selfref && $self->modify('from_hex');
754              
755 2         4 my $str = shift;
756 2         5 my @r = @_;
757              
758             # If called as a class method, initialize a new object.
759              
760 2 50       12 $self = $class -> bzero(@r) unless $selfref;
761              
762 2 50       6 if (my @parts = $class -> _hex_str_to_flt_lib_parts($str)) {
763              
764             # The value is an integer iff the exponent is non-negative.
765              
766 2 50       5 if ($parts[2] eq '+') {
767 2         5 $self -> {sign} = $parts[0];
768 2         7 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
769 2         7 return $self -> round(@r);
770             }
771              
772             # The value is not an integer, so upgrade if upgrading is enabled.
773              
774 0 0       0 return $upgrade -> new($str, @r) if defined $upgrade;
775             }
776              
777 0         0 return $self -> bnan(@r);
778             }
779              
780             # Create a Math::BigInt from an octal string.
781              
782             sub from_oct {
783 2     2 1 664 my $self = shift;
784 2         5 my $selfref = ref $self;
785 2   33     11 my $class = $selfref || $self;
786              
787             # Don't modify constant (read-only) objects.
788              
789 2 50 33     7 return $self if $selfref && $self->modify('from_oct');
790              
791 2         3 my $str = shift;
792 2         6 my @r = @_;
793              
794             # If called as a class method, initialize a new object.
795              
796 2 50       8 $self = $class -> bzero(@r) unless $selfref;
797              
798 2 50       13 if (my @parts = $class -> _oct_str_to_flt_lib_parts($str)) {
799              
800             # The value is an integer iff the exponent is non-negative.
801              
802 2 50       17 if ($parts[2] eq '+') {
803 2         8 $self -> {sign} = $parts[0];
804 2         12 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
805 2         11 return $self -> round(@r);
806             }
807              
808             # The value is not an integer, so upgrade if upgrading is enabled.
809              
810 0 0       0 return $upgrade -> new($str, @r) if defined $upgrade;
811             }
812              
813 0         0 return $self -> bnan(@r);
814             }
815              
816             # Create a Math::BigInt from a binary string.
817              
818             sub from_bin {
819 53     53 1 744 my $self = shift;
820 53         87 my $selfref = ref $self;
821 53   33     173 my $class = $selfref || $self;
822              
823             # Don't modify constant (read-only) objects.
824              
825 53 50 33     136 return $self if $selfref && $self->modify('from_bin');
826              
827 53         81 my $str = shift;
828 53         88 my @r = @_;
829              
830             # If called as a class method, initialize a new object.
831              
832 53 50       165 $self = $class -> bzero(@r) unless $selfref;
833              
834 53 50       165 if (my @parts = $class -> _bin_str_to_flt_lib_parts($str)) {
835              
836             # The value is an integer iff the exponent is non-negative.
837              
838 53 50       139 if ($parts[2] eq '+') {
839 53         119 $self -> {sign} = $parts[0];
840 53         186 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
841 53         174 return $self -> round(@r);
842             }
843              
844             # The value is not an integer, so upgrade if upgrading is enabled.
845              
846 0 0       0 return $upgrade -> new($str, @r) if defined $upgrade;
847             }
848              
849 0         0 return $self -> bnan(@r);
850             }
851              
852             # Create a Math::BigInt from a byte string.
853              
854             sub from_bytes {
855 0     0 1 0 my $self = shift;
856 0         0 my $selfref = ref $self;
857 0   0     0 my $class = $selfref || $self;
858              
859             # Don't modify constant (read-only) objects.
860              
861 0 0 0     0 return $self if $selfref && $self->modify('from_bytes');
862              
863 0 0       0 croak("from_bytes() requires a newer version of the $LIB library.")
864             unless $LIB->can('_from_bytes');
865              
866 0         0 my $str = shift;
867 0         0 my @r = @_;
868              
869             # If called as a class method, initialize a new object.
870              
871 0 0       0 $self = $class -> bzero(@r) unless $selfref;
872 0         0 $self -> {sign} = '+';
873 0         0 $self -> {value} = $LIB -> _from_bytes($str);
874 0         0 return $self -> round(@r);
875             }
876              
877             sub from_base {
878 0     0 1 0 my $self = shift;
879 0         0 my $selfref = ref $self;
880 0   0     0 my $class = $selfref || $self;
881              
882             # Don't modify constant (read-only) objects.
883              
884 0 0 0     0 return $self if $selfref && $self->modify('from_base');
885              
886 0         0 my ($str, $base, $cs, @r) = @_; # $cs is the collation sequence
887              
888 0 0       0 $base = $class->new($base) unless ref($base);
889              
890 0 0 0     0 croak("the base must be a finite integer >= 2")
891             if $base < 2 || ! $base -> is_int();
892              
893             # If called as a class method, initialize a new object.
894              
895 0 0       0 $self = $class -> bzero() unless $selfref;
896              
897             # If no collating sequence is given, pass some of the conversions to
898             # methods optimized for those cases.
899              
900 0 0       0 unless (defined $cs) {
901 0 0       0 return $self -> from_bin($str, @r) if $base == 2;
902 0 0       0 return $self -> from_oct($str, @r) if $base == 8;
903 0 0       0 return $self -> from_hex($str, @r) if $base == 16;
904 0 0       0 if ($base == 10) {
905 0         0 my $tmp = $class -> from_dec($str, @r);
906 0         0 $self -> {value} = $tmp -> {value};
907 0         0 $self -> {sign} = '+';
908 0         0 return $self -> bround(@r);
909             }
910             }
911              
912 0 0       0 croak("from_base() requires a newer version of the $LIB library.")
913             unless $LIB->can('_from_base');
914              
915 0         0 $self -> {sign} = '+';
916             $self -> {value}
917 0 0       0 = $LIB->_from_base($str, $base -> {value}, defined($cs) ? $cs : ());
918 0         0 return $self -> bround(@r);
919             }
920              
921             sub from_base_num {
922 0     0 1 0 my $self = shift;
923 0         0 my $selfref = ref $self;
924 0   0     0 my $class = $selfref || $self;
925              
926             # Don't modify constant (read-only) objects.
927              
928 0 0 0     0 return $self if $selfref && $self->modify('from_base_num');
929              
930             # Make sure we have an array of non-negative, finite, numerical objects.
931              
932 0         0 my $nums = shift;
933 0         0 $nums = [ @$nums ]; # create new reference
934              
935 0         0 for my $i (0 .. $#$nums) {
936             # Make sure we have an object.
937 0 0 0     0 $nums -> [$i] = $class -> new($nums -> [$i])
938             unless defined(blessed($nums -> [$i]))
939             && $nums -> [$i] -> isa(__PACKAGE__);
940             # Make sure we have a finite, non-negative integer.
941 0 0 0     0 croak "the elements must be finite non-negative integers"
942             if $nums -> [$i] -> is_neg() || ! $nums -> [$i] -> is_int();
943             }
944              
945 0         0 my $base = shift;
946 0 0 0     0 $base = $class -> new($base)
947             unless defined(blessed($base)) && $base -> isa(__PACKAGE__);
948              
949 0         0 my @r = @_;
950              
951             # If called as a class method, initialize a new object.
952              
953 0 0       0 $self = $class -> bzero(@r) unless $selfref;
954              
955 0 0       0 croak("from_base_num() requires a newer version of the $LIB library.")
956             unless $LIB->can('_from_base_num');
957              
958 0         0 $self -> {sign} = '+';
959 0         0 $self -> {value} = $LIB -> _from_base_num([ map { $_ -> {value} } @$nums ],
960 0         0 $base -> {value});
961              
962 0         0 return $self -> round(@r);
963             }
964              
965             sub bzero {
966             # create/assign '+0'
967              
968             # Class::method(...) -> Class->method(...)
969 2343 50 66 2343 1 30931 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      33        
970             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
971             {
972             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
973             # " use is as a method instead";
974 0         0 unshift @_, __PACKAGE__;
975             }
976              
977 2343         5213 my $self = shift;
978 2343         3748 my $selfref = ref $self;
979 2343   66     6319 my $class = $selfref || $self;
980              
981 2343 50       4772 $self->import() if $IMPORT == 0; # make require work
982              
983             # Don't modify constant (read-only) objects.
984              
985 2343 50 66     5823 return $self if $selfref && $self->modify('bzero');
986              
987             # Get the rounding parameters, if any.
988              
989 2343         4150 my @r = @_;
990              
991             # If called as a class method, initialize a new object.
992              
993 2343 100       5772 $self = bless {}, $class unless $selfref;
994              
995 2343         5362 $self->{sign} = '+';
996 2343         6370 $self->{value} = $LIB->_zero();
997              
998             # If rounding parameters are given as arguments, use them. If no rounding
999             # parameters are given, and if called as a class method, initialize the new
1000             # instance with the class variables.
1001              
1002 2343 100       7655 if (@r) {
    100          
1003 12 50 100     67 croak "can't specify both accuracy and precision"
      66        
1004             if @r >= 2 && defined($r[0]) && defined($r[1]);
1005 12         28 $self->{_a} = $_[0];
1006 12         24 $self->{_p} = $_[1];
1007             } elsif (!$selfref) {
1008 1897         4446 $self->{_a} = $class -> accuracy();
1009 1897         4754 $self->{_p} = $class -> precision();
1010             }
1011              
1012 2343         7164 return $self;
1013             }
1014              
1015             sub bone {
1016             # Create or assign '+1' (or -1 if given sign '-').
1017              
1018             # Class::method(...) -> Class->method(...)
1019 476 50 66 476 1 10138 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1020             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1021             {
1022             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1023             # " use is as a method instead";
1024 0         0 unshift @_, __PACKAGE__;
1025             }
1026              
1027 476         1002 my $self = shift;
1028 476         795 my $selfref = ref $self;
1029 476   66     1179 my $class = $selfref || $self;
1030              
1031 476 50       974 $self->import() if $IMPORT == 0; # make require work
1032              
1033             # Don't modify constant (read-only) objects.
1034              
1035 476 50 66     1451 return $self if $selfref && $self->modify('bone');
1036              
1037 476         963 my ($sign, @r) = @_;
1038              
1039             # Get the sign.
1040              
1041 476 100 100     1637 if (defined($_[0]) && $_[0] =~ /^\s*([+-])\s*$/) {
1042 104         314 $sign = $1;
1043 104         169 shift;
1044             } else {
1045 372         629 $sign = '+';
1046             }
1047              
1048             # If called as a class method, initialize a new object.
1049              
1050 476 100       1090 $self = bless {}, $class unless $selfref;
1051              
1052 476         1132 $self->{sign} = $sign;
1053 476         1508 $self->{value} = $LIB->_one();
1054              
1055             # If rounding parameters are given as arguments, use them. If no rounding
1056             # parameters are given, and if called as a class method, initialize the new
1057             # instance with the class variables.
1058              
1059 476 100       1632 if (@r) {
    100          
1060 18 50 100     83 croak "can't specify both accuracy and precision"
      66        
1061             if @r >= 2 && defined($r[0]) && defined($r[1]);
1062 18         38 $self->{_a} = $_[0];
1063 18         32 $self->{_p} = $_[1];
1064             } elsif (!$selfref) {
1065 266         650 $self->{_a} = $class -> accuracy();
1066 266         633 $self->{_p} = $class -> precision();
1067             }
1068              
1069 476         2714 return $self;
1070             }
1071              
1072             sub binf {
1073             # create/assign a '+inf' or '-inf'
1074              
1075             # Class::method(...) -> Class->method(...)
1076 2088 50 66 2088 1 20282 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1077             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1078             {
1079             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1080             # " use is as a method instead";
1081 0         0 unshift @_, __PACKAGE__;
1082             }
1083              
1084 2088         4299 my $self = shift;
1085 2088         3328 my $selfref = ref $self;
1086 2088   66     5450 my $class = $selfref || $self;
1087              
1088             {
1089 51     51   490 no strict 'refs';
  51         139  
  51         23660  
  2088         3140  
1090 2088 100       2734 if (${"${class}::_trap_inf"}) {
  2088         8239  
1091 5         519 croak("Tried to create +-inf in $class->binf()");
1092             }
1093             }
1094              
1095 2083 50       4281 $self->import() if $IMPORT == 0; # make require work
1096              
1097             # Don't modify constant (read-only) objects.
1098              
1099 2083 50 66     4987 return $self if $selfref && $self->modify('binf');
1100              
1101             # Get the sign.
1102              
1103 2083         3397 my $sign = '+'; # default is to return positive infinity
1104 2083 100 66     9812 if (defined($_[0]) && $_[0] =~ /^\s*([+-])(inf|$)/i) {
1105 2032         4216 $sign = $1;
1106 2032         2806 shift;
1107             }
1108              
1109             # Get the rounding parameters, if any.
1110              
1111 2083         3989 my @r = @_;
1112              
1113             # If called as a class method, initialize a new object.
1114              
1115 2083 100       5196 $self = bless {}, $class unless $selfref;
1116              
1117 2083         6235 $self -> {sign} = $sign . 'inf';
1118 2083         6664 $self -> {value} = $LIB -> _zero();
1119              
1120             # If rounding parameters are given as arguments, use them. If no rounding
1121             # parameters are given, and if called as a class method, initialize the new
1122             # instance with the class variables.
1123              
1124 2083 100       6093 if (@r) {
    100          
1125 575 50 33     3064 croak "can't specify both accuracy and precision"
      33        
1126             if @r >= 2 && defined($r[0]) && defined($r[1]);
1127 575         1159 $self->{_a} = $_[0];
1128 575         996 $self->{_p} = $_[1];
1129             } elsif (!$selfref) {
1130 1235         2903 $self->{_a} = $class -> accuracy();
1131 1235         3013 $self->{_p} = $class -> precision();
1132             }
1133              
1134 2083         20252 return $self;
1135             }
1136              
1137             sub bnan {
1138             # create/assign a 'NaN'
1139              
1140             # Class::method(...) -> Class->method(...)
1141 2246 50 66 2246 1 24038 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1142             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1143             {
1144             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1145             # " use is as a method instead";
1146 0         0 unshift @_, __PACKAGE__;
1147             }
1148              
1149 2246         4471 my $self = shift;
1150 2246         3779 my $selfref = ref($self);
1151 2246   66     5392 my $class = $selfref || $self;
1152              
1153             {
1154 51     51   498 no strict 'refs';
  51         121  
  51         854000  
  2246         3221  
1155 2246 100       3055 if (${"${class}::_trap_nan"}) {
  2246         8506  
1156 4         569 croak("Tried to create NaN in $class->bnan()");
1157             }
1158             }
1159              
1160 2242 50       5058 $self->import() if $IMPORT == 0; # make require work
1161              
1162             # Don't modify constant (read-only) objects.
1163              
1164 2242 50 66     6774 return $self if $selfref && $self->modify('bnan');
1165              
1166             # Get the rounding parameters, if any.
1167              
1168 2242         4168 my @r = @_;
1169              
1170 2242 100       5060 $self = bless {}, $class unless $selfref;
1171              
1172 2242         5181 $self -> {sign} = $nan;
1173 2242         6912 $self -> {value} = $LIB -> _zero();
1174              
1175             # If rounding parameters are given as arguments, use them. If no rounding
1176             # parameters are given, and if called as a class method, initialize the new
1177             # instance with the class variables.
1178              
1179 2242 100       6589 if (@r) {
    100          
1180 541 50 66     2442 croak "can't specify both accuracy and precision"
      33        
1181             if @r >= 2 && defined($r[0]) && defined($r[1]);
1182 541         1002 $self->{_a} = $_[0];
1183 541         941 $self->{_p} = $_[1];
1184             } elsif (!$selfref) {
1185 900         2335 $self->{_a} = $class -> accuracy();
1186 900         2264 $self->{_p} = $class -> precision();
1187             }
1188              
1189 2242         19393 return $self;
1190             }
1191              
1192             sub bpi {
1193              
1194             # Class::method(...) -> Class->method(...)
1195 9 50 33 9 1 242 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      33        
1196             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1197             {
1198             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1199             # " use is as a method instead";
1200 0         0 unshift @_, __PACKAGE__;
1201             }
1202              
1203             # Called as Argument list
1204             # --------- -------------
1205             # Math::BigFloat->bpi() ("Math::BigFloat")
1206             # Math::BigFloat->bpi(10) ("Math::BigFloat", 10)
1207             # $x->bpi() ($x)
1208             # $x->bpi(10) ($x, 10)
1209             # Math::BigFloat::bpi() ()
1210             # Math::BigFloat::bpi(10) (10)
1211             #
1212             # In ambiguous cases, we favour the OO-style, so the following case
1213             #
1214             # $n = Math::BigFloat->new("10");
1215             # $x = Math::BigFloat->bpi($n);
1216             #
1217             # which gives an argument list with the single element $n, is resolved as
1218             #
1219             # $n->bpi();
1220              
1221 9         22 my $self = shift;
1222 9         23 my $selfref = ref $self;
1223 9   33     37 my $class = $selfref || $self;
1224 9         25 my @r = @_; # rounding paramters
1225              
1226 9 50       28 if ($selfref) { # bpi() called as an instance method
1227 0 0       0 return $self if $self -> modify('bpi');
1228             } else { # bpi() called as a class method
1229 9         23 $self = bless {}, $class; # initialize new instance
1230             }
1231              
1232 9 50       26 return $upgrade -> bpi(@r) if defined $upgrade;
1233              
1234             # hard-wired to "3"
1235 9         22 $self -> {sign} = '+';
1236 9         34 $self -> {value} = $LIB -> _new("3");
1237 9         31 $self = $self -> round(@r);
1238 9         93 return $self;
1239             }
1240              
1241             sub copy {
1242 4824     4824 1 11543 my ($x, $class);
1243 4824 50       10258 if (ref($_[0])) { # $y = $x -> copy()
1244 4824         7591 $x = shift;
1245 4824         7792 $class = ref($x);
1246             } else { # $y = Math::BigInt -> copy($y)
1247 0         0 $class = shift;
1248 0         0 $x = shift;
1249             }
1250              
1251 4824 50       10123 carp "Rounding is not supported for ", (caller(0))[3], "()" if @_;
1252              
1253 4824         9559 my $copy = bless {}, $class;
1254              
1255 4824         11270 $copy->{sign} = $x->{sign};
1256 4824         13390 $copy->{value} = $LIB->_copy($x->{value});
1257 4824 100       11649 $copy->{_a} = $x->{_a} if exists $x->{_a};
1258 4824 100       10309 $copy->{_p} = $x->{_p} if exists $x->{_p};
1259              
1260 4824         13756 return $copy;
1261             }
1262              
1263             sub as_int {
1264 3 50   3 1 19 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1265 3 50       11 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1266              
1267             # If called as an instance method, and the instance class is something we
1268             # upgrade to, $x might not be a Math::BigInt, so don't just call copy().
1269              
1270 3 50       24 return $x -> copy() if $x -> isa("Math::BigInt");
1271              
1272             # disable upgrading and downgrading
1273              
1274 0         0 my $upg = Math::BigInt -> upgrade();
1275 0         0 my $dng = Math::BigInt -> downgrade();
1276 0         0 Math::BigInt -> upgrade(undef);
1277 0         0 Math::BigInt -> downgrade(undef);
1278              
1279 0         0 my $y = Math::BigInt -> new($x);
1280              
1281             # reset upgrading and downgrading
1282              
1283 0         0 Math::BigInt -> upgrade($upg);
1284 0         0 Math::BigInt -> downgrade($dng);
1285              
1286 0         0 return $y;
1287             }
1288              
1289             sub as_float {
1290 343 50   343 1 1042 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1291 343 50       733 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1292              
1293             # disable upgrading and downgrading
1294              
1295 343         1945 require Math::BigFloat;
1296 343         844 my $upg = Math::BigFloat -> upgrade();
1297 343         853 my $dng = Math::BigFloat -> downgrade();
1298 343         880 Math::BigFloat -> upgrade(undef);
1299 343         822 Math::BigFloat -> downgrade(undef);
1300              
1301 343         945 my $y = Math::BigFloat -> new($x);
1302              
1303             # reset upgrading and downgrading
1304              
1305 343         1182 Math::BigFloat -> upgrade($upg);
1306 343         876 Math::BigFloat -> downgrade($dng);
1307              
1308 343         891 return $y;
1309             }
1310              
1311             sub as_rat {
1312 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1313 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1314              
1315             # disable upgrading and downgrading
1316              
1317 0         0 require Math::BigRat;
1318 0         0 my $upg = Math::BigRat -> upgrade();
1319 0         0 my $dng = Math::BigRat -> downgrade();
1320 0         0 Math::BigRat -> upgrade(undef);
1321 0         0 Math::BigRat -> downgrade(undef);
1322              
1323 0         0 my $y = Math::BigRat -> new($x);
1324              
1325             # reset upgrading and downgrading
1326              
1327 0         0 Math::BigRat -> upgrade($upg);
1328 0         0 Math::BigRat -> downgrade($dng);
1329              
1330 0         0 return $y;
1331             }
1332              
1333             ###############################################################################
1334             # Boolean methods
1335             ###############################################################################
1336              
1337             sub is_zero {
1338             # return true if arg (BINT or num_str) is zero (array '+', '0')
1339 32532 100   32532 1 75167 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1340              
1341 32532 100       115917 return 0 if $x->{sign} !~ /^\+$/; # -, NaN & +-inf aren't
1342 29725         82263 $LIB->_is_zero($x->{value});
1343             }
1344              
1345             sub is_one {
1346             # return true if arg (BINT or num_str) is +1, or -1 if sign is given
1347 1731 100   1731 1 7039 my (undef, $x, $sign) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1348              
1349 1731 100 100     5619 $sign = '+' if !defined($sign) || $sign ne '-';
1350              
1351 1731 100       4558 return 0 if $x->{sign} ne $sign; # -1 != +1, NaN, +-inf aren't either
1352 1125         3273 $LIB->_is_one($x->{value});
1353             }
1354              
1355             sub is_finite {
1356 364 50   364 1 1020 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1357 364   100     1721 return $x->{sign} eq '+' || $x->{sign} eq '-';
1358             }
1359              
1360             sub is_inf {
1361             # return true if arg (BINT or num_str) is +-inf
1362 38693 100   38693 1 95331 my (undef, $x, $sign) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1363              
1364 38693 100       73357 if (defined $sign) {
1365 7080 100       13519 $sign = '[+-]inf' if $sign eq ''; # +- doesn't matter, only that's inf
1366 7080 100       31448 $sign = "[$1]inf" if $sign =~ /^([+-])(inf)?$/; # extract '+' or '-'
1367 7080 100       109210 return $x->{sign} =~ /^$sign$/ ? 1 : 0;
1368             }
1369 31613 100       93105 $x->{sign} =~ /^[+-]inf$/ ? 1 : 0; # only +-inf is infinity
1370             }
1371              
1372             sub is_nan {
1373             # return true if arg (BINT or num_str) is NaN
1374 48850 100   48850 1 113872 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1375              
1376 48850 100       173314 $x->{sign} eq $nan ? 1 : 0;
1377             }
1378              
1379             sub is_positive {
1380             # return true when arg (BINT or num_str) is positive (> 0)
1381 454 100   454 1 7026 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1382              
1383 454 100       1299 return 1 if $x->{sign} eq '+inf'; # +inf is positive
1384              
1385             # 0+ is neither positive nor negative
1386 439 100 100     1928 ($x->{sign} eq '+' && !$x->is_zero()) ? 1 : 0;
1387             }
1388              
1389             sub is_negative {
1390             # return true when arg (BINT or num_str) is negative (< 0)
1391 2826 100   2826 1 12400 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1392              
1393 2826 100       12983 $x->{sign} =~ /^-/ ? 1 : 0; # -inf is negative, but NaN is not
1394             }
1395              
1396             sub is_non_negative {
1397             # Return true if argument is non-negative (>= 0).
1398 64 100   64 1 5439 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1399              
1400 64 100       481 return 1 if $x->{sign} =~ /^\+/;
1401 32 50       135 return 1 if $x -> is_zero();
1402 32         304 return 0;
1403             }
1404              
1405             sub is_non_positive {
1406             # Return true if argument is non-positive (<= 0).
1407 64 100   64 1 5561 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1408              
1409 64 100       428 return 1 if $x->{sign} =~ /^\-/;
1410 40 100       283 return 1 if $x -> is_zero();
1411 32         319 return 0;
1412             }
1413              
1414             sub is_odd {
1415             # return true when arg (BINT or num_str) is odd, false for even
1416 185 50   185 1 884 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1417              
1418 185 100       665 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
1419 178         550 $LIB->_is_odd($x->{value});
1420             }
1421              
1422             sub is_even {
1423             # return true when arg (BINT or num_str) is even, false for odd
1424 44 50   44 1 516 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1425              
1426 44 100       187 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
1427 40         152 $LIB->_is_even($x->{value});
1428             }
1429              
1430             sub is_int {
1431             # return true when arg (BINT or num_str) is an integer
1432 46 50   46 1 384 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1433              
1434 46 100       510 $x->{sign} =~ /^[+-]$/ ? 1 : 0; # inf/-inf/NaN aren't
1435             }
1436              
1437             ###############################################################################
1438             # Comparison methods
1439             ###############################################################################
1440              
1441             sub bcmp {
1442             # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
1443             # (BINT or num_str, BINT or num_str) return cond_code
1444              
1445             # set up parameters
1446 2401 100 66 2401 1 11806 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1447             ? (ref($_[0]), @_)
1448             : objectify(2, @_);
1449              
1450 2401 50       5139 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1451              
1452 2401 100 66     5821 return $upgrade->bcmp($x, $y)
      100        
1453             if defined($upgrade) && (!$x->isa(__PACKAGE__) || !$y->isa(__PACKAGE__));
1454              
1455 2400 100 100     12707 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/)) {
1456             # handle +-inf and NaN
1457 320 100 100     1666 return if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1458 256 100 66     872 return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
1459 229 100       909 return +1 if $x->{sign} eq '+inf';
1460 133 100       641 return -1 if $x->{sign} eq '-inf';
1461 19 100       121 return -1 if $y->{sign} eq '+inf';
1462 11         86 return +1;
1463             }
1464              
1465             # check sign for speed first
1466 2080 100 100     7063 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
1467 1818 100 100     4703 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
1468              
1469             # have same sign, so compare absolute values. Don't make tests for zero
1470             # here because it's actually slower than testing in Calc (especially w/ Pari
1471             # et al)
1472              
1473             # post-normalized compare for internal use (honors signs)
1474 1624 100       3431 if ($x->{sign} eq '+') {
1475             # $x and $y both > 0
1476 1534         4862 return $LIB->_acmp($x->{value}, $y->{value});
1477             }
1478              
1479             # $x && $y both < 0
1480 90         335 $LIB->_acmp($y->{value}, $x->{value}); # swapped acmp (lib returns 0, 1, -1)
1481             }
1482              
1483             sub bacmp {
1484             # Compares 2 values, ignoring their signs.
1485             # Returns one of undef, <0, =0, >0. (suitable for sort)
1486             # (BINT, BINT) return cond_code
1487              
1488             # set up parameters
1489 238 50 33 238 1 2366 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1490             ? (ref($_[0]), @_)
1491             : objectify(2, @_);
1492              
1493 238 50       595 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1494              
1495 238 50 33     764 return $upgrade->bacmp($x, $y)
      66        
1496             if defined($upgrade) && (!$x->isa(__PACKAGE__) || !$y->isa(__PACKAGE__));
1497              
1498 238 100 100     1353 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/)) {
1499             # handle +-inf and NaN
1500 72 100 100     509 return if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1501 44 100 100     457 return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
1502 28 100 66     257 return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
1503 12         112 return -1;
1504             }
1505 166         687 $LIB->_acmp($x->{value}, $y->{value}); # lib does only 0, 1, -1
1506             }
1507              
1508             sub beq {
1509 427 100 66 427 1 2437 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1510             ? (undef, @_)
1511             : objectify(2, @_);
1512              
1513 427 50       1108 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1514              
1515 427         1334 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
1516 427   100     4132 return defined($cmp) && !$cmp;
1517             }
1518              
1519             sub bne {
1520 18 50 33 18 1 127 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1521             ? (undef, @_)
1522             : objectify(2, @_);
1523              
1524 18 50       59 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1525              
1526 18         57 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
1527 18 50 33     116 return defined($cmp) && !$cmp ? '' : 1;
1528             }
1529              
1530             sub blt {
1531 619 100 66 619 1 2932 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1532             ? (undef, @_)
1533             : objectify(2, @_);
1534              
1535 619 50       1734 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1536              
1537 619         1669 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
1538 619   100     5358 return defined($cmp) && $cmp < 0;
1539             }
1540              
1541             sub ble {
1542 1478 100 66 1478 1 6534 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1543             ? (undef, @_)
1544             : objectify(2, @_);
1545              
1546 1478 50       3102 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1547              
1548 1478         3923 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
1549 1478   100     8740 return defined($cmp) && $cmp <= 0;
1550             }
1551              
1552             sub bgt {
1553 1385 100 66 1385 1 6513 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1554             ? (undef, @_)
1555             : objectify(2, @_);
1556              
1557 1385 50       3062 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1558              
1559 1385         3702 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
1560 1385   66     8074 return defined($cmp) && $cmp > 0;
1561             }
1562              
1563             sub bge {
1564 317 100 66 317 1 1818 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1565             ? (undef, @_)
1566             : objectify(2, @_);
1567              
1568 317 50       1844 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1569              
1570 317         929 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
1571 317   100     2264 return defined($cmp) && $cmp >= 0;
1572             }
1573              
1574             ###############################################################################
1575             # Arithmetic methods
1576             ###############################################################################
1577              
1578             sub bneg {
1579             # (BINT or num_str) return BINT
1580             # negate number or make a negated number from string
1581 486 50   486 1 1829 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1582              
1583 486 50       1455 return $x if $x->modify('bneg');
1584              
1585 486 50 66     1206 return $upgrade -> bneg($x, @r)
1586             if defined($upgrade) && !$x->isa(__PACKAGE__);
1587              
1588             # Don't negate +0 so we always have the normalized form +0. Does nothing for
1589             # 'NaN'.
1590             $x->{sign} =~ tr/+-/-+/
1591 486 100 100     2095 unless $x->{sign} eq '+' && $LIB->_is_zero($x->{value});
1592              
1593 486         1239 $x -> round(@r);
1594             }
1595              
1596             sub babs {
1597             # (BINT or num_str) return BINT
1598             # make number absolute, or return absolute BINT from string
1599 321 100   321 1 5024 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1600              
1601 321 50       1076 return $x if $x->modify('babs');
1602              
1603 321 50 66     831 return $upgrade -> babs($x, @r)
1604             if defined($upgrade) && !$x->isa(__PACKAGE__);
1605              
1606 321         873 $x->{sign} =~ s/^-/+/;
1607              
1608 321         800 $x -> round(@r);
1609             }
1610              
1611             sub bsgn {
1612             # Signum function.
1613 18 50   18 1 225 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1614              
1615 18 50       64 return $x if $x->modify('bsgn');
1616              
1617 18 50 33     52 return $upgrade -> bsgn($x, @r)
1618             if defined($upgrade) && !$x->isa(__PACKAGE__);
1619              
1620 18 100       54 return $x -> bone("+", @r) if $x -> is_pos();
1621 12 100       31 return $x -> bone("-", @r) if $x -> is_neg();
1622              
1623 6         21 $x -> round(@r);
1624             }
1625              
1626             sub bnorm {
1627             # (numstr or BINT) return BINT
1628             # Normalize number -- no-op here
1629 792 50   792 1 364690 my ($class, $x, @r) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
1630              
1631             # This method is called from the rounding methods, so if this method
1632             # supports rounding by calling the rounding methods, we get an infinite
1633             # recursion.
1634              
1635 792 50       1943 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1636              
1637 792         7242 $x;
1638             }
1639              
1640             sub binc {
1641             # increment arg by one
1642 191 50   191 1 817 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1643              
1644 191 50       569 return $x if $x->modify('binc');
1645              
1646 191 100 100     438 return $x->round(@r) if $x -> is_inf() || $x -> is_nan();
1647              
1648 175 50 66     489 return $upgrade -> binc($x, @r)
1649             if defined($upgrade) && !$x -> isa(__PACKAGE__);
1650              
1651 175 100       472 if ($x->{sign} eq '+') {
    50          
1652 101         377 $x->{value} = $LIB->_inc($x->{value});
1653             } elsif ($x->{sign} eq '-') {
1654 74         248 $x->{value} = $LIB->_dec($x->{value});
1655 74 100       216 $x->{sign} = '+' if $LIB->_is_zero($x->{value}); # -1 +1 => -0 => +0
1656             }
1657              
1658 175         434 return $x->round(@r);
1659             }
1660              
1661             sub bdec {
1662             # decrement arg by one
1663 31 50   31 1 322 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1664              
1665 31 50       116 return $x if $x->modify('bdec');
1666              
1667 31 100 100     80 return $x->round(@r) if $x -> is_inf() || $x -> is_nan();
1668              
1669 19 50 66     102 return $upgrade -> bdec($x, @r)
1670             if defined($upgrade) && !$x -> isa(__PACKAGE__);;
1671              
1672 19 100       103 if ($x->{sign} eq '-') {
    50          
1673 4         23 $x->{value} = $LIB->_inc($x->{value});
1674             } elsif ($x->{sign} eq '+') {
1675 15 100       78 if ($LIB->_is_zero($x->{value})) { # +1 - 1 => +0
1676 4         20 $x->{value} = $LIB->_one();
1677 4         15 $x->{sign} = '-';
1678             } else {
1679 11         66 $x->{value} = $LIB->_dec($x->{value});
1680             }
1681             }
1682              
1683 19         59 return $x->round(@r);
1684             }
1685              
1686             #sub bstrcmp {
1687             # my $self = shift;
1688             # my $selfref = ref $self;
1689             # my $class = $selfref || $self;
1690             #
1691             # croak 'bstrcmp() is an instance method, not a class method'
1692             # unless $selfref;
1693             # croak 'Wrong number of arguments for bstrcmp()' unless @_ == 1;
1694             #
1695             # return $self -> bstr() CORE::cmp shift;
1696             #}
1697             #
1698             #sub bstreq {
1699             # my $self = shift;
1700             # my $selfref = ref $self;
1701             # my $class = $selfref || $self;
1702             #
1703             # croak 'bstreq() is an instance method, not a class method'
1704             # unless $selfref;
1705             # croak 'Wrong number of arguments for bstreq()' unless @_ == 1;
1706             #
1707             # my $cmp = $self -> bstrcmp(shift);
1708             # return defined($cmp) && ! $cmp;
1709             #}
1710             #
1711             #sub bstrne {
1712             # my $self = shift;
1713             # my $selfref = ref $self;
1714             # my $class = $selfref || $self;
1715             #
1716             # croak 'bstrne() is an instance method, not a class method'
1717             # unless $selfref;
1718             # croak 'Wrong number of arguments for bstrne()' unless @_ == 1;
1719             #
1720             # my $cmp = $self -> bstrcmp(shift);
1721             # return defined($cmp) && ! $cmp ? '' : 1;
1722             #}
1723             #
1724             #sub bstrlt {
1725             # my $self = shift;
1726             # my $selfref = ref $self;
1727             # my $class = $selfref || $self;
1728             #
1729             # croak 'bstrlt() is an instance method, not a class method'
1730             # unless $selfref;
1731             # croak 'Wrong number of arguments for bstrlt()' unless @_ == 1;
1732             #
1733             # my $cmp = $self -> bstrcmp(shift);
1734             # return defined($cmp) && $cmp < 0;
1735             #}
1736             #
1737             #sub bstrle {
1738             # my $self = shift;
1739             # my $selfref = ref $self;
1740             # my $class = $selfref || $self;
1741             #
1742             # croak 'bstrle() is an instance method, not a class method'
1743             # unless $selfref;
1744             # croak 'Wrong number of arguments for bstrle()' unless @_ == 1;
1745             #
1746             # my $cmp = $self -> bstrcmp(shift);
1747             # return defined($cmp) && $cmp <= 0;
1748             #}
1749             #
1750             #sub bstrgt {
1751             # my $self = shift;
1752             # my $selfref = ref $self;
1753             # my $class = $selfref || $self;
1754             #
1755             # croak 'bstrgt() is an instance method, not a class method'
1756             # unless $selfref;
1757             # croak 'Wrong number of arguments for bstrgt()' unless @_ == 1;
1758             #
1759             # my $cmp = $self -> bstrcmp(shift);
1760             # return defined($cmp) && $cmp > 0;
1761             #}
1762             #
1763             #sub bstrge {
1764             # my $self = shift;
1765             # my $selfref = ref $self;
1766             # my $class = $selfref || $self;
1767             #
1768             # croak 'bstrge() is an instance method, not a class method'
1769             # unless $selfref;
1770             # croak 'Wrong number of arguments for bstrge()' unless @_ == 1;
1771             #
1772             # my $cmp = $self -> bstrcmp(shift);
1773             # return defined($cmp) && $cmp >= 0;
1774             #}
1775              
1776             sub badd {
1777             # add second arg (BINT or string) to first (BINT) (modifies first)
1778             # return result as BINT
1779              
1780             # set up parameters
1781 1818 100 100 1818 1 12229 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1782             ? (ref($_[0]), @_)
1783             : objectify(2, @_);
1784              
1785 1818 50       5241 return $x if $x->modify('badd');
1786              
1787 1818         3014 $r[3] = $y; # no push!
1788              
1789 1818 100 66     4468 return $upgrade->badd($x, $y, @r)
      100        
1790             if defined($upgrade) && (!$x->isa(__PACKAGE__) || !$y->isa(__PACKAGE__));
1791              
1792             # Inf and NaN handling
1793 1816 100 100     9260 if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/) {
1794             # NaN first
1795 197 100 100     941 return $x->bnan(@r) if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1796             # Inf handling
1797 109 100 100     607 if (($x->{sign} =~ /^[+-]inf$/) && ($y->{sign} =~ /^[+-]inf$/)) {
1798             # +Inf + +Inf or -Inf + -Inf => same, rest is NaN
1799 54 100       203 return $x->round(@r) if $x->{sign} eq $y->{sign};
1800 24         102 return $x->bnan(@r);
1801             }
1802             # ±Inf + something => ±Inf
1803             # something + ±Inf => ±Inf
1804 55 100       211 if ($y->{sign} =~ /^[+-]inf$/) {
1805 35         83 $x->{sign} = $y->{sign};
1806             }
1807 55         175 return $x -> round(@r);
1808             }
1809              
1810             ($x->{value}, $x->{sign})
1811 1619         5601 = $LIB -> _sadd($x->{value}, $x->{sign}, $y->{value}, $y->{sign});
1812 1619         4281 $x->round(@r);
1813             }
1814              
1815             sub bsub {
1816             # (BINT or num_str, BINT or num_str) return BINT
1817             # subtract second arg from first, modify first
1818              
1819             # set up parameters
1820 1116 100 100 1116 1 7976 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1821             ? (ref($_[0]), @_)
1822             : objectify(2, @_);
1823              
1824 1116 50       3355 return $x if $x -> modify('bsub');
1825              
1826 1116 50 33     2691 return $upgrade -> bsub($x, $y, @r)
      66        
1827             if defined($upgrade) && (!$x->isa(__PACKAGE__) || !$y->isa(__PACKAGE__));
1828              
1829 1116 100       2480 return $x -> round(@r) if $y -> is_zero();
1830              
1831             # To correctly handle the lone special case $x -> bsub($x), we note the
1832             # sign of $x, then flip the sign from $y, and if the sign of $x did change,
1833             # too, then we caught the special case:
1834              
1835 1083         2150 my $xsign = $x -> {sign};
1836 1083         2303 $y -> {sign} =~ tr/+-/-+/; # does nothing for NaN
1837 1083 100       2421 if ($xsign ne $x -> {sign}) {
1838             # special case of $x -> bsub($x) results in 0
1839 12 100       70 return $x -> bzero(@r) if $xsign =~ /^[+-]$/;
1840 6         29 return $x -> bnan(@r); # NaN, -inf, +inf
1841             }
1842              
1843 1071         2545 $x = $x -> badd($y, @r); # badd() does not leave internal zeros
1844 1071         2367 $y -> {sign} =~ tr/+-/-+/; # refix $y (does nothing for NaN)
1845 1071         5329 $x; # already rounded by badd() or no rounding
1846             }
1847              
1848             sub bmul {
1849             # multiply the first number by the second number
1850             # (BINT or num_str, BINT or num_str) return BINT
1851              
1852             # set up parameters
1853 1644 100 100 1644 1 10878 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1854             ? (ref($_[0]), @_)
1855             : objectify(2, @_);
1856              
1857 1644 50       4853 return $x if $x->modify('bmul');
1858              
1859 1644 100 100     6155 return $x->bnan(@r) if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1860              
1861             # inf handling
1862 1592 100 100     5650 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/)) {
1863 52 100 100     159 return $x->bnan(@r) if $x->is_zero() || $y->is_zero();
1864             # result will always be +-inf:
1865             # +inf * +/+inf => +inf, -inf * -/-inf => +inf
1866             # +inf * -/-inf => -inf, -inf * +/+inf => -inf
1867 40 100 100     245 return $x->binf(@r) if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
1868 30 100 100     234 return $x->binf(@r) if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
1869 20         61 return $x->binf('-', @r);
1870             }
1871              
1872 1540 100 66     4004 return $upgrade->bmul($x, $y, @r)
      100        
1873             if defined($upgrade) && (!$x->isa(__PACKAGE__) || !$y->isa(__PACKAGE__));
1874              
1875 1532         2425 $r[3] = $y; # no push here
1876              
1877 1532 100       3578 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-'; # +1 * +1 or -1 * -1 => +
1878              
1879 1532         4476 $x->{value} = $LIB->_mul($x->{value}, $y->{value}); # do actual math
1880 1532 100       4155 $x->{sign} = '+' if $LIB->_is_zero($x->{value}); # no -0
1881              
1882 1532         3698 $x->round(@r);
1883             }
1884              
1885             sub bmuladd {
1886             # multiply two numbers and then add the third to the result
1887             # (BINT or num_str, BINT or num_str, BINT or num_str) return BINT
1888              
1889             # set up parameters
1890 177 50 33 177 1 3005 my ($class, $x, $y, $z, @r)
1891             = ref($_[0]) && ref($_[0]) eq ref($_[1]) && ref($_[1]) eq ref($_[2])
1892             ? (ref($_[0]), @_)
1893             : objectify(3, @_);
1894              
1895 177 50       535 return $x if $x->modify('bmuladd');
1896              
1897             # x, y, and z are finite numbers
1898              
1899 177 100 100     1118 if ($x->{sign} =~ /^[+-]$/ &&
      100        
1900             $y->{sign} =~ /^[+-]$/ &&
1901             $z->{sign} =~ /^[+-]$/)
1902             {
1903 141 50 0     349 return $upgrade->bmuladd($x, $y, $z, @r)
      33        
1904             if defined($upgrade) && (!$x->isa(__PACKAGE__) ||
1905             !$y->isa(__PACKAGE__) ||
1906             !$z->isa(__PACKAGE__));
1907              
1908             # TODO: what if $y and $z have A or P set?
1909 141         240 $r[3] = $z; # no push here
1910              
1911 141         208 my $zs = $z->{sign};
1912 141         212 my $zv = $z->{value};
1913 141 50       513 $zv = $LIB -> _copy($zv) if refaddr($x) eq refaddr($z);
1914              
1915 141 100       333 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-'; # +1 * +1 or -1 * -1 => +
1916 141         480 $x->{value} = $LIB->_mul($x->{value}, $y->{value}); # do actual math
1917 141 100       378 $x->{sign} = '+' if $LIB->_is_zero($x->{value}); # no -0
1918              
1919             ($x->{value}, $x->{sign})
1920 141         484 = $LIB -> _sadd($x->{value}, $x->{sign}, $zv, $zs);
1921 141         388 return $x->round(@r);
1922             }
1923              
1924             # At least one of x, y, and z is a NaN
1925              
1926             return $x->bnan(@r) if (($x->{sign} eq $nan) ||
1927             ($y->{sign} eq $nan) ||
1928 36 100 100     249 ($z->{sign} eq $nan));
      100        
1929              
1930             # At least one of x, y, and z is an Inf
1931              
1932 12 100       70 if ($x->{sign} eq "-inf") {
    50          
    0          
    0          
    0          
1933              
1934 6 100       32 if ($y -> is_neg()) { # x = -inf, y < 0
    50          
1935 3 50       43 if ($z->{sign} eq "-inf") {
1936 0         0 return $x->bnan(@r);
1937             } else {
1938 3         25 return $x->binf("+", @r);
1939             }
1940             } elsif ($y -> is_zero()) { # x = -inf, y = 0
1941 0         0 return $x->bnan(@r);
1942             } else { # x = -inf, y > 0
1943 3 50       22 if ($z->{sign} eq "+inf") {
1944 0         0 return $x->bnan(@r);
1945             } else {
1946 3         21 return $x->binf("-", @r);
1947             }
1948             }
1949              
1950             } elsif ($x->{sign} eq "+inf") {
1951              
1952 6 100       28 if ($y -> is_neg()) { # x = +inf, y < 0
    50          
1953 3 50       18 if ($z->{sign} eq "+inf") {
1954 0         0 return $x->bnan(@r);
1955             } else {
1956 3         14 return $x->binf("-", @r);
1957             }
1958             } elsif ($y -> is_zero()) { # x = +inf, y = 0
1959 0         0 return $x->bnan(@r);
1960             } else { # x = +inf, y > 0
1961 3 50       16 if ($z->{sign} eq "-inf") {
1962 0         0 return $x->bnan(@r);
1963             } else {
1964 3         46 return $x->binf("+", @r);
1965             }
1966             }
1967              
1968             } elsif ($x -> is_neg()) {
1969              
1970 0 0       0 if ($y->{sign} eq "-inf") { # -inf < x < 0, y = -inf
    0          
1971 0 0       0 if ($z->{sign} eq "-inf") {
1972 0         0 return $x->bnan(@r);
1973             } else {
1974 0         0 return $x->binf("+", @r);
1975             }
1976             } elsif ($y->{sign} eq "+inf") { # -inf < x < 0, y = +inf
1977 0 0       0 if ($z->{sign} eq "+inf") {
1978 0         0 return $x->bnan(@r);
1979             } else {
1980 0         0 return $x->binf("-", @r);
1981             }
1982             } else { # -inf < x < 0, -inf < y < +inf
1983 0 0       0 if ($z->{sign} eq "-inf") {
    0          
1984 0         0 return $x->binf("-", @r);
1985             } elsif ($z->{sign} eq "+inf") {
1986 0         0 return $x->binf("+", @r);
1987             }
1988             }
1989              
1990             } elsif ($x -> is_zero()) {
1991              
1992 0 0       0 if ($y->{sign} eq "-inf") { # x = 0, y = -inf
    0          
1993 0         0 return $x->bnan(@r);
1994             } elsif ($y->{sign} eq "+inf") { # x = 0, y = +inf
1995 0         0 return $x->bnan(@r);
1996             } else { # x = 0, -inf < y < +inf
1997 0 0       0 if ($z->{sign} eq "-inf") {
    0          
1998 0         0 return $x->binf("-", @r);
1999             } elsif ($z->{sign} eq "+inf") {
2000 0         0 return $x->binf("+", @r);
2001             }
2002             }
2003              
2004             } elsif ($x -> is_pos()) {
2005              
2006 0 0       0 if ($y->{sign} eq "-inf") { # 0 < x < +inf, y = -inf
    0          
2007 0 0       0 if ($z->{sign} eq "+inf") {
2008 0         0 return $x->bnan(@r);
2009             } else {
2010 0         0 return $x->binf("-", @r);
2011             }
2012             } elsif ($y->{sign} eq "+inf") { # 0 < x < +inf, y = +inf
2013 0 0       0 if ($z->{sign} eq "-inf") {
2014 0         0 return $x->bnan(@r);
2015             } else {
2016 0         0 return $x->binf("+", @r);
2017             }
2018             } else { # 0 < x < +inf, -inf < y < +inf
2019 0 0       0 if ($z->{sign} eq "-inf") {
    0          
2020 0         0 return $x->binf("-", @r);
2021             } elsif ($z->{sign} eq "+inf") {
2022 0         0 return $x->binf("+", @r);
2023             }
2024             }
2025             }
2026              
2027 0         0 die;
2028             }
2029              
2030             sub bdiv {
2031             # This does floored division, where the quotient is floored, i.e., rounded
2032             # towards negative infinity. As a consequence, the remainder has the same
2033             # sign as the divisor.
2034              
2035             # Set up parameters.
2036 1467 100 100 1467 1 15656 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2037             ? (ref($_[0]), @_)
2038             : objectify(2, @_);
2039              
2040 1467 50       4480 return $x if $x -> modify('bdiv');
2041              
2042 1467         2540 my $wantarray = wantarray; # call only once
2043              
2044             # At least one argument is NaN. Return NaN for both quotient and the
2045             # modulo/remainder.
2046              
2047 1467 100 100     3178 if ($x -> is_nan() || $y -> is_nan()) {
2048 51 100       255 return $wantarray ? ($x -> bnan(@r), $class -> bnan(@r))
2049             : $x -> bnan(@r);
2050             }
2051              
2052             # Divide by zero and modulo zero.
2053             #
2054             # Division: Use the common convention that x / 0 is inf with the same sign
2055             # as x, except when x = 0, where we return NaN. This is also what earlier
2056             # versions did.
2057             #
2058             # Modulo: In modular arithmetic, the congruence relation z = x (mod y)
2059             # means that there is some integer k such that z - x = k y. If y = 0, we
2060             # get z - x = 0 or z = x. This is also what earlier versions did, except
2061             # that 0 % 0 returned NaN.
2062             #
2063             # inf / 0 = inf inf % 0 = inf
2064             # 5 / 0 = inf 5 % 0 = 5
2065             # 0 / 0 = NaN 0 % 0 = 0
2066             # -5 / 0 = -inf -5 % 0 = -5
2067             # -inf / 0 = -inf -inf % 0 = -inf
2068              
2069 1416 100       3293 if ($y -> is_zero()) {
2070 67         142 my $rem;
2071 67 100       161 if ($wantarray) {
2072 32         121 $rem = $x -> copy() -> round(@r);
2073             }
2074 67 100       154 if ($x -> is_zero()) {
2075 17         73 $x = $x -> bnan(@r);
2076             } else {
2077 50         163 $x = $x -> binf($x -> {sign}, @r);
2078             }
2079 64 100       478 return $wantarray ? ($x, $rem) : $x;
2080             }
2081              
2082             # Numerator (dividend) is +/-inf, and denominator is finite and non-zero.
2083             # The divide by zero cases are covered above. In all of the cases listed
2084             # below we return the same as core Perl.
2085             #
2086             # inf / -inf = NaN inf % -inf = NaN
2087             # inf / -5 = -inf inf % -5 = NaN
2088             # inf / 5 = inf inf % 5 = NaN
2089             # inf / inf = NaN inf % inf = NaN
2090             #
2091             # -inf / -inf = NaN -inf % -inf = NaN
2092             # -inf / -5 = inf -inf % -5 = NaN
2093             # -inf / 5 = -inf -inf % 5 = NaN
2094             # -inf / inf = NaN -inf % inf = NaN
2095              
2096 1349 100       2995 if ($x -> is_inf()) {
2097 96         174 my $rem;
2098 96 100       336 $rem = $class -> bnan(@r) if $wantarray;
2099 96 100       216 if ($y -> is_inf()) {
2100 48         195 $x = $x -> bnan(@r);
2101             } else {
2102 48 100       165 my $sign = $x -> bcmp(0) == $y -> bcmp(0) ? '+' : '-';
2103 48         169 $x = $x -> binf($sign, @r);
2104             }
2105 96 100       704 return $wantarray ? ($x, $rem) : $x;
2106             }
2107              
2108             # Denominator (divisor) is +/-inf. The cases when the numerator is +/-inf
2109             # are covered above. In the modulo cases (in the right column) we return
2110             # the same as core Perl, which does floored division, so for consistency we
2111             # also do floored division in the division cases (in the left column).
2112             #
2113             # -5 / inf = -1 -5 % inf = inf
2114             # 0 / inf = 0 0 % inf = 0
2115             # 5 / inf = 0 5 % inf = 5
2116             #
2117             # -5 / -inf = 0 -5 % -inf = -5
2118             # 0 / -inf = 0 0 % -inf = 0
2119             # 5 / -inf = -1 5 % -inf = -inf
2120              
2121 1253 100       2269 if ($y -> is_inf()) {
2122 80         152 my $rem;
2123 80 100 100     219 if ($x -> is_zero() || $x -> bcmp(0) == $y -> bcmp(0)) {
2124 56 100       232 $rem = $x -> copy() -> round(@r) if $wantarray;
2125 56         189 $x = $x -> bzero(@r);
2126             } else {
2127 24 100       110 $rem = $class -> binf($y -> {sign}, @r) if $wantarray;
2128 24         88 $x = $x -> bone('-', @r);
2129             }
2130 80 100       591 return $wantarray ? ($x, $rem) : $x;
2131             }
2132              
2133             # At this point, both the numerator and denominator are finite numbers, and
2134             # the denominator (divisor) is non-zero.
2135              
2136             # Division might return a non-integer result, so upgrade unconditionally, if
2137             # upgrading is enabled.
2138              
2139 1173 100       2984 return $upgrade -> bdiv($x, $y, @r) if defined $upgrade;
2140              
2141 1103         1892 $r[3] = $y; # no push!
2142              
2143             # Inialize remainder.
2144              
2145 1103         2494 my $rem = $class -> bzero();
2146              
2147             # Are both operands the same object, i.e., like $x -> bdiv($x)? If so,
2148             # flipping the sign of $y also flips the sign of $x.
2149              
2150 1103         2117 my $xsign = $x -> {sign};
2151 1103         1766 my $ysign = $y -> {sign};
2152              
2153 1103         2471 $y -> {sign} =~ tr/+-/-+/; # Flip the sign of $y, and see ...
2154 1103         2089 my $same = $xsign ne $x -> {sign}; # ... if that changed the sign of $x.
2155 1103         1844 $y -> {sign} = $ysign; # Re-insert the original sign.
2156              
2157 1103 100       1856 if ($same) {
2158 6         18 $x = $x -> bone();
2159             } else {
2160             ($x -> {value}, $rem -> {value}) =
2161 1097         3488 $LIB -> _div($x -> {value}, $y -> {value});
2162              
2163 1097 100       3237 if ($LIB -> _is_zero($rem -> {value})) {
2164 522 100 100     1591 if ($xsign eq $ysign || $LIB -> _is_zero($x -> {value})) {
2165 469         915 $x -> {sign} = '+';
2166             } else {
2167 53         116 $x -> {sign} = '-';
2168             }
2169             } else {
2170 575 100       1251 if ($xsign eq $ysign) {
2171 524         1000 $x -> {sign} = '+';
2172             } else {
2173 51 100       130 if ($xsign eq '+') {
2174 24         73 $x = $x -> badd(1);
2175             } else {
2176 27         87 $x = $x -> bsub(1);
2177             }
2178 51         116 $x -> {sign} = '-';
2179             }
2180             }
2181             }
2182              
2183 1103         2536 $x = $x -> round(@r);
2184              
2185 1103 100       2409 if ($wantarray) {
2186 491 100       1293 unless ($LIB -> _is_zero($rem -> {value})) {
2187 379 100       747 if ($xsign ne $ysign) {
2188 24         57 $rem = $y -> copy() -> babs() -> bsub($rem);
2189             }
2190 379         698 $rem -> {sign} = $ysign;
2191             }
2192 491         858 $rem -> {_a} = $x -> {_a};
2193 491         731 $rem -> {_p} = $x -> {_p};
2194 491         936 $rem = $rem -> round(@r);
2195 491         2085 return ($x, $rem);
2196             }
2197              
2198 612         5670 return $x;
2199             }
2200              
2201             sub btdiv {
2202             # This does truncated division, where the quotient is truncted, i.e.,
2203             # rounded towards zero.
2204             #
2205             # ($q, $r) = $x -> btdiv($y) returns $q and $r so that $q is int($x / $y)
2206             # and $q * $y + $r = $x.
2207              
2208             # Set up parameters
2209 366 50 33 366 1 5663 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2210             ? (ref($_[0]), @_)
2211             : objectify(2, @_);
2212              
2213 366 50       1146 return $x if $x -> modify('btdiv');
2214              
2215 366         613 my $wantarray = wantarray; # call only once
2216              
2217             # At least one argument is NaN. Return NaN for both quotient and the
2218             # modulo/remainder.
2219              
2220 366 50 33     819 if ($x -> is_nan() || $y -> is_nan()) {
2221 0 0       0 return $wantarray ? ($x -> bnan(@r), $class -> bnan(@r))
2222             : $x -> bnan(@r);
2223             }
2224              
2225             # Divide by zero and modulo zero.
2226             #
2227             # Division: Use the common convention that x / 0 is inf with the same sign
2228             # as x, except when x = 0, where we return NaN. This is also what earlier
2229             # versions did.
2230             #
2231             # Modulo: In modular arithmetic, the congruence relation z = x (mod y)
2232             # means that there is some integer k such that z - x = k y. If y = 0, we
2233             # get z - x = 0 or z = x. This is also what earlier versions did, except
2234             # that 0 % 0 returned NaN.
2235             #
2236             # inf / 0 = inf inf % 0 = inf
2237             # 5 / 0 = inf 5 % 0 = 5
2238             # 0 / 0 = NaN 0 % 0 = 0
2239             # -5 / 0 = -inf -5 % 0 = -5
2240             # -inf / 0 = -inf -inf % 0 = -inf
2241              
2242 366 100       853 if ($y -> is_zero()) {
2243 30         54 my $rem;
2244 30 100       62 if ($wantarray) {
2245 15         57 $rem = $x -> copy(@r);
2246             }
2247 30 100       55 if ($x -> is_zero()) {
2248 6         21 $x = $x -> bnan(@r);
2249             } else {
2250 24         67 $x = $x -> binf($x -> {sign}, @r);
2251             }
2252 30 100       260 return $wantarray ? ($x, $rem) : $x;
2253             }
2254              
2255             # Numerator (dividend) is +/-inf, and denominator is finite and non-zero.
2256             # The divide by zero cases are covered above. In all of the cases listed
2257             # below we return the same as core Perl.
2258             #
2259             # inf / -inf = NaN inf % -inf = NaN
2260             # inf / -5 = -inf inf % -5 = NaN
2261             # inf / 5 = inf inf % 5 = NaN
2262             # inf / inf = NaN inf % inf = NaN
2263             #
2264             # -inf / -inf = NaN -inf % -inf = NaN
2265             # -inf / -5 = inf -inf % -5 = NaN
2266             # -inf / 5 = -inf -inf % 5 = NaN
2267             # -inf / inf = NaN -inf % inf = NaN
2268              
2269 336 100       708 if ($x -> is_inf()) {
2270 48         71 my $rem;
2271 48 100       118 $rem = $class -> bnan(@r) if $wantarray;
2272 48 100       102 if ($y -> is_inf()) {
2273 24         63 $x = $x -> bnan(@r);
2274             } else {
2275 24 100       77 my $sign = $x -> bcmp(0) == $y -> bcmp(0) ? '+' : '-';
2276 24         71 $x = $x -> binf($sign,@r );
2277             }
2278 48 100       404 return $wantarray ? ($x, $rem) : $x;
2279             }
2280              
2281             # Denominator (divisor) is +/-inf. The cases when the numerator is +/-inf
2282             # are covered above. In the modulo cases (in the right column) we return
2283             # the same as core Perl, which does floored division, so for consistency we
2284             # also do floored division in the division cases (in the left column).
2285             #
2286             # -5 / inf = 0 -5 % inf = -5
2287             # 0 / inf = 0 0 % inf = 0
2288             # 5 / inf = 0 5 % inf = 5
2289             #
2290             # -5 / -inf = 0 -5 % -inf = -5
2291             # 0 / -inf = 0 0 % -inf = 0
2292             # 5 / -inf = 0 5 % -inf = 5
2293              
2294 288 100       526 if ($y -> is_inf()) {
2295 36         55 my $rem;
2296 36 100       93 $rem = $x -> copy() -> round(@r) if $wantarray;
2297 36         91 $x = $x -> bzero(@r);
2298 36 100       308 return $wantarray ? ($x, $rem) : $x;
2299             }
2300              
2301             # Division might return a non-integer result, so upgrade unconditionally, if
2302             # upgrading is enabled.
2303              
2304 252 50       548 return $upgrade -> btdiv($x, $y, @r) if defined $upgrade;
2305              
2306 252         451 $r[3] = $y; # no push!
2307              
2308             # Inialize remainder.
2309              
2310 252         578 my $rem = $class -> bzero();
2311              
2312             # Are both operands the same object, i.e., like $x -> bdiv($x)? If so,
2313             # flipping the sign of $y also flips the sign of $x.
2314              
2315 252         486 my $xsign = $x -> {sign};
2316 252         395 my $ysign = $y -> {sign};
2317              
2318 252         511 $y -> {sign} =~ tr/+-/-+/; # Flip the sign of $y, and see ...
2319 252         461 my $same = $xsign ne $x -> {sign}; # ... if that changed the sign of $x.
2320 252         390 $y -> {sign} = $ysign; # Re-insert the original sign.
2321              
2322 252 50       455 if ($same) {
2323 0         0 $x = $x -> bone(@r);
2324             } else {
2325             ($x -> {value}, $rem -> {value}) =
2326 252         783 $LIB -> _div($x -> {value}, $y -> {value});
2327              
2328 252 100       602 $x -> {sign} = $xsign eq $ysign ? '+' : '-';
2329 252 100       651 $x -> {sign} = '+' if $LIB -> _is_zero($x -> {value});
2330 252         632 $x = $x -> round(@r);
2331             }
2332              
2333 252 100       525 if (wantarray) {
2334 126         252 $rem -> {sign} = $xsign;
2335 126 100       301 $rem -> {sign} = '+' if $LIB -> _is_zero($rem -> {value});
2336 126         239 $rem -> {_a} = $x -> {_a};
2337 126         175 $rem -> {_p} = $x -> {_p};
2338 126         235 $rem = $rem -> round(@r);
2339 126         584 return ($x, $rem);
2340             }
2341              
2342 126         1534 return $x;
2343             }
2344              
2345             sub bmod {
2346             # This is the remainder after floored division.
2347              
2348             # Set up parameters.
2349 700 100 100 700 1 4453 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2350             ? (ref($_[0]), @_)
2351             : objectify(2, @_);
2352              
2353 700 50       2262 return $x if $x -> modify('bmod');
2354              
2355 700         1322 $r[3] = $y; # no push!
2356              
2357             # At least one argument is NaN.
2358              
2359 700 100 100     1512 if ($x -> is_nan() || $y -> is_nan()) {
2360 27         112 return $x -> bnan(@r);
2361             }
2362              
2363             # Modulo zero. See documentation for bdiv().
2364              
2365 673 100       1634 if ($y -> is_zero()) {
2366 34         100 return $x -> round(@r);
2367             }
2368              
2369             # Numerator (dividend) is +/-inf.
2370              
2371 639 100       1495 if ($x -> is_inf()) {
2372 48         193 return $x -> bnan(@r);
2373             }
2374              
2375             # Denominator (divisor) is +/-inf.
2376              
2377 591 100       1165 if ($y -> is_inf()) {
2378 40 100 100     199 if ($x -> is_zero() || $x -> bcmp(0) == $y -> bcmp(0)) {
2379 28         103 return $x -> round(@r);
2380             } else {
2381 12         85 return $x -> binf($y -> sign(), @r);
2382             }
2383             }
2384              
2385 551 50 33     1562 return $upgrade -> bmod($x, $y, @r)
      66        
2386             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
2387             !$y -> isa(__PACKAGE__));
2388              
2389             # Calc new sign and in case $y == +/- 1, return $x.
2390              
2391 551         1676 $x -> {value} = $LIB -> _mod($x -> {value}, $y -> {value});
2392 551 100       1373 if ($LIB -> _is_zero($x -> {value})) {
2393 154         327 $x -> {sign} = '+'; # do not leave -0
2394             } else {
2395             $x -> {value} = $LIB -> _sub($y -> {value}, $x -> {value}, 1) # $y-$x
2396 397 100       1334 if ($x -> {sign} ne $y -> {sign});
2397 397         750 $x -> {sign} = $y -> {sign};
2398             }
2399              
2400 551         1347 $x -> round(@r);
2401             }
2402              
2403             sub btmod {
2404             # Remainder after truncated division.
2405              
2406             # set up parameters
2407 0 0 0 0 1 0 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2408             ? (ref($_[0]), @_)
2409             : objectify(2, @_);
2410              
2411 0 0       0 return $x if $x -> modify('btmod');
2412              
2413             # At least one argument is NaN.
2414              
2415 0 0 0     0 if ($x -> is_nan() || $y -> is_nan()) {
2416 0         0 return $x -> bnan(@r);
2417             }
2418              
2419             # Modulo zero. See documentation for btdiv().
2420              
2421 0 0       0 if ($y -> is_zero()) {
2422 0         0 return $x -> round(@r);
2423             }
2424              
2425             # Numerator (dividend) is +/-inf.
2426              
2427 0 0       0 if ($x -> is_inf()) {
2428 0         0 return $x -> bnan(@r);
2429             }
2430              
2431             # Denominator (divisor) is +/-inf.
2432              
2433 0 0       0 if ($y -> is_inf()) {
2434 0         0 return $x -> round(@r);
2435             }
2436              
2437 0 0 0     0 return $upgrade -> btmod($x, $y, @r)
      0        
2438             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
2439             !$y -> isa(__PACKAGE__));
2440              
2441 0         0 $r[3] = $y; # no push!
2442              
2443 0         0 my $xsign = $x -> {sign};
2444              
2445 0         0 $x -> {value} = $LIB -> _mod($x -> {value}, $y -> {value});
2446              
2447 0         0 $x -> {sign} = $xsign;
2448 0 0       0 $x -> {sign} = '+' if $LIB -> _is_zero($x -> {value});
2449 0         0 $x -> round(@r);
2450             }
2451              
2452             sub bmodinv {
2453             # Return modular multiplicative inverse:
2454             #
2455             # z is the modular inverse of x (mod y) if and only if
2456             #
2457             # x*z ≡ 1 (mod y)
2458             #
2459             # If the modulus y is larger than one, x and z are relative primes (i.e.,
2460             # their greatest common divisor is one).
2461             #
2462             # If no modular multiplicative inverse exists, NaN is returned.
2463              
2464             # set up parameters
2465 243 50 33 243 1 2552 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2466             ? (ref($_[0]), @_)
2467             : objectify(2, @_);
2468              
2469 243 50       732 return $x if $x->modify('bmodinv');
2470              
2471             # Return NaN if one or both arguments is +inf, -inf, or nan.
2472              
2473             return $x->bnan(@r) if ($y->{sign} !~ /^[+-]$/ ||
2474 243 100 100     1267 $x->{sign} !~ /^[+-]$/);
2475              
2476             # Return NaN if $y is zero; 1 % 0 makes no sense.
2477              
2478 222 50       567 return $x->bnan(@r) if $y->is_zero();
2479              
2480             # Return 0 in the trivial case. $x % 1 or $x % -1 is zero for all finite
2481             # integers $x.
2482              
2483 222 100 66     545 return $x->bzero(@r) if ($y->is_one('+') ||
2484             $y->is_one('-'));
2485              
2486 159 50 0     413 return $upgrade -> bmodinv($x, $y, @r)
      33        
2487             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
2488             !$y -> isa(__PACKAGE__));
2489              
2490             # Return NaN if $x = 0, or $x modulo $y is zero. The only valid case when
2491             # $x = 0 is when $y = 1 or $y = -1, but that was covered above.
2492             #
2493             # Note that computing $x modulo $y here affects the value we'll feed to
2494             # $LIB->_modinv() below when $x and $y have opposite signs. E.g., if $x =
2495             # 5 and $y = 7, those two values are fed to _modinv(), but if $x = -5 and
2496             # $y = 7, the values fed to _modinv() are $x = 2 (= -5 % 7) and $y = 7.
2497             # The value if $x is affected only when $x and $y have opposite signs.
2498              
2499 159         424 $x = $x->bmod($y);
2500 159 100       352 return $x->bnan(@r) if $x->is_zero();
2501              
2502             # Compute the modular multiplicative inverse of the absolute values. We'll
2503             # correct for the signs of $x and $y later. Return NaN if no GCD is found.
2504              
2505 123         420 ($x->{value}, $x->{sign}) = $LIB->_modinv($x->{value}, $y->{value});
2506 123 100       418 return $x->bnan(@r) if !defined($x->{value});
2507              
2508             # Library inconsistency workaround: _modinv() in Math::BigInt::GMP versions
2509             # <= 1.32 return undef rather than a "+" for the sign.
2510              
2511 102 50       226 $x->{sign} = '+' unless defined $x->{sign};
2512              
2513             # When one or both arguments are negative, we have the following
2514             # relations. If x and y are positive:
2515             #
2516             # modinv(-x, -y) = -modinv(x, y)
2517             # modinv(-x, y) = y - modinv(x, y) = -modinv(x, y) (mod y)
2518             # modinv( x, -y) = modinv(x, y) - y = modinv(x, y) (mod -y)
2519              
2520             # We must swap the sign of the result if the original $x is negative.
2521             # However, we must compensate for ignoring the signs when computing the
2522             # inverse modulo. The net effect is that we must swap the sign of the
2523             # result if $y is negative.
2524              
2525 102 100       268 $x = $x -> bneg() if $y->{sign} eq '-';
2526              
2527             # Compute $x modulo $y again after correcting the sign.
2528              
2529 102 100       286 $x = $x -> bmod($y) if $x->{sign} ne $y->{sign};
2530              
2531 102         280 $x -> round(@r);
2532             }
2533              
2534             sub bmodpow {
2535             # Modular exponentiation. Raises a very large number to a very large
2536             # exponent in a given very large modulus quickly, thanks to binary
2537             # exponentiation. Supports negative exponents.
2538 501 50 33 501 1 7947 my ($class, $num, $exp, $mod, @r)
2539             = ref($_[0]) && ref($_[0]) eq ref($_[1]) && ref($_[1]) eq ref($_[2])
2540             ? (ref($_[0]), @_)
2541             : objectify(3, @_);
2542              
2543 501 50       1559 return $num if $num->modify('bmodpow');
2544              
2545             # When the exponent 'e' is negative, use the following relation, which is
2546             # based on finding the multiplicative inverse 'd' of 'b' modulo 'm':
2547             #
2548             # b^(-e) (mod m) = d^e (mod m) where b*d = 1 (mod m)
2549              
2550 501 100       1367 $num = $num -> bmodinv($mod) if ($exp->{sign} eq '-');
2551              
2552             # Check for valid input. All operands must be finite, and the modulus must
2553             # be non-zero.
2554              
2555             return $num->bnan(@r) if ($num->{sign} =~ /NaN|inf/ || # NaN, -inf, +inf
2556             $exp->{sign} =~ /NaN|inf/ || # NaN, -inf, +inf
2557 501 100 100     2769 $mod->{sign} =~ /NaN|inf/); # NaN, -inf, +inf
      100        
2558              
2559             # Modulo zero. See documentation for Math::BigInt's bmod() method.
2560              
2561 435 100       1104 if ($mod -> is_zero()) {
2562 3 50       25 if ($num -> is_zero()) {
2563 0         0 return $class -> bnan(@r);
2564             } else {
2565 3         20 return $num -> copy(@r);
2566             }
2567             }
2568              
2569 432 50 0     1155 return $upgrade -> bmodinv($num, $exp, $mod, @r)
      33        
2570             if defined($upgrade) && (!$num -> isa(__PACKAGE__) ||
2571             !$exp -> isa(__PACKAGE__) ||
2572             !$mod -> ($class));
2573              
2574             # Compute 'a (mod m)', ignoring the signs on 'a' and 'm'. If the resulting
2575             # value is zero, the output is also zero, regardless of the signs on 'a' and
2576             # 'm'.
2577              
2578 432         1282 my $value = $LIB->_modpow($num->{value}, $exp->{value}, $mod->{value});
2579 432         746 my $sign = '+';
2580              
2581             # If the resulting value is non-zero, we have four special cases, depending
2582             # on the signs on 'a' and 'm'.
2583              
2584 432 100       1005 unless ($LIB->_is_zero($value)) {
2585              
2586             # There is a negative sign on 'a' (= $num**$exp) only if the number we
2587             # are exponentiating ($num) is negative and the exponent ($exp) is odd.
2588              
2589 213 100 100     727 if ($num->{sign} eq '-' && $exp->is_odd()) {
2590              
2591             # When both the number 'a' and the modulus 'm' have a negative sign,
2592             # use this relation:
2593             #
2594             # -a (mod -m) = -(a (mod m))
2595              
2596 21 50       72 if ($mod->{sign} eq '-') {
2597 0         0 $sign = '-';
2598             }
2599              
2600             # When only the number 'a' has a negative sign, use this relation:
2601             #
2602             # -a (mod m) = m - (a (mod m))
2603              
2604             else {
2605             # Use copy of $mod since _sub() modifies the first argument.
2606 21         59 my $mod = $LIB->_copy($mod->{value});
2607 21         71 $value = $LIB->_sub($mod, $value);
2608 21         51 $sign = '+';
2609             }
2610              
2611             } else {
2612              
2613             # When only the modulus 'm' has a negative sign, use this relation:
2614             #
2615             # a (mod -m) = (a (mod m)) - m
2616             # = -(m - (a (mod m)))
2617              
2618 192 100       415 if ($mod->{sign} eq '-') {
2619             # Use copy of $mod since _sub() modifies the first argument.
2620 3         23 my $mod = $LIB->_copy($mod->{value});
2621 3         15 $value = $LIB->_sub($mod, $value);
2622 3         10 $sign = '-';
2623             }
2624              
2625             # When neither the number 'a' nor the modulus 'm' have a negative
2626             # sign, directly return the already computed value.
2627             #
2628             # (a (mod m))
2629              
2630             }
2631              
2632             }
2633              
2634 432         761 $num->{value} = $value;
2635 432         630 $num->{sign} = $sign;
2636              
2637 432         976 return $num -> round(@r);
2638             }
2639              
2640             sub bpow {
2641             # (BINT or num_str, BINT or num_str) return BINT
2642             # compute power of two numbers -- stolen from Knuth Vol 2 pg 233
2643             # modifies first argument
2644              
2645             # set up parameters
2646 575 100 100 575 1 3332 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2647             ? (ref($_[0]), @_)
2648             : objectify(2, @_);
2649              
2650 575 50       1822 return $x if $x -> modify('bpow');
2651              
2652             # $x and/or $y is a NaN
2653 575 100 100     1292 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
2654              
2655             # $x and/or $y is a +/-Inf
2656 510 100       1256 if ($x -> is_inf("-")) {
    100          
    100          
    100          
2657 39 100       126 return $x -> bzero(@r) if $y -> is_negative();
2658 23 100       68 return $x -> bnan(@r) if $y -> is_zero();
2659 20 100       78 return $x -> round(@r) if $y -> is_odd();
2660 10         75 return $x -> bneg(@r);
2661             } elsif ($x -> is_inf("+")) {
2662 35 100       115 return $x -> bzero(@r) if $y -> is_negative();
2663 19 100       101 return $x -> bnan(@r) if $y -> is_zero();
2664 16         62 return $x -> round(@r);
2665             } elsif ($y -> is_inf("-")) {
2666 21 100       85 return $x -> bnan(@r) if $x -> is_one("-");
2667 18 100       47 return $x -> binf("+", @r) if $x -> is_zero();
2668 15 100       39 return $x -> bone(@r) if $x -> is_one("+");
2669 12         45 return $x -> bzero(@r);
2670             } elsif ($y -> is_inf("+")) {
2671 21 100       83 return $x -> bnan(@r) if $x -> is_one("-");
2672 18 100       55 return $x -> bzero(@r) if $x -> is_zero();
2673 15 100       42 return $x -> bone(@r) if $x -> is_one("+");
2674 12         52 return $x -> binf("+", @r);
2675             }
2676              
2677 394 100       1277 if ($x -> is_zero()) {
2678 26 100       66 return $x -> bone(@r) if $y -> is_zero();
2679 22 100       64 return $x -> binf(@r) if $y -> is_negative();
2680 11         52 return $x -> round(@r);
2681             }
2682              
2683 368 100       1058 if ($x -> is_one("+")) {
2684 28         78 return $x -> round(@r);
2685             }
2686              
2687 340 100       757 if ($x -> is_one("-")) {
2688 31 100       92 return $x -> round(@r) if $y -> is_odd();
2689 14         75 return $x -> bneg(@r);
2690             }
2691              
2692 309 100       872 return $upgrade -> bpow($x, $y, @r) if defined $upgrade;
2693              
2694             # We don't support finite non-integers, so return zero. The reason for
2695             # returning zero, not NaN, is that all output is in the open interval (0,1),
2696             # and truncating that to integer gives zero.
2697              
2698 271 100 66     1415 if ($y->{sign} eq '-' || !$y -> isa(__PACKAGE__)) {
2699 36         122 return $x -> bzero(@r);
2700             }
2701              
2702 235         529 $r[3] = $y; # no push!
2703              
2704 235         827 $x->{value} = $LIB -> _pow($x->{value}, $y->{value});
2705 235 100 100     1701 $x->{sign} = $x -> is_negative() && $y -> is_odd() ? '-' : '+';
2706 235         673 $x -> round(@r);
2707             }
2708              
2709             sub blog {
2710             # Return the logarithm of the operand. If a second operand is defined, that
2711             # value is used as the base, otherwise the base is assumed to be Euler's
2712             # constant.
2713              
2714 199     199 1 2604 my ($class, $x, $base, @r);
2715              
2716             # Only objectify the base if it is defined, since an undefined base, as in
2717             # $x->blog() or $x->blog(undef) signals that the base is Euler's number =
2718             # 2.718281828...
2719              
2720 199 50 33     669 if (!ref($_[0]) && $_[0] =~ /^[a-z]\w*(?:::\w+)*$/i) {
2721             # E.g., Math::BigInt->blog(256, 2)
2722 0 0       0 ($class, $x, $base, @r) =
2723             defined $_[2] ? objectify(2, @_) : objectify(1, @_);
2724             } else {
2725             # E.g., $x->blog(2) or the deprecated Math::BigInt::blog(256, 2)
2726 199 100       679 ($class, $x, $base, @r) =
2727             defined $_[1] ? objectify(2, @_) : objectify(1, @_);
2728             }
2729              
2730 199 50       715 return $x if $x->modify('blog');
2731              
2732             # Handle all exception cases and all trivial cases. I have used Wolfram
2733             # Alpha (http://www.wolframalpha.com) as the reference for these cases.
2734              
2735 199 100       444 return $x -> bnan(@r) if $x -> is_nan();
2736              
2737 190 100       422 if (defined $base) {
2738 160 50 33     938 $base = $class -> new($base)
2739             unless defined(blessed($base)) && $base -> isa(__PACKAGE__);
2740 160 100 100     344 if ($base -> is_nan() || $base -> is_one()) {
    100 100        
    100          
2741 12         115 return $x -> bnan(@r);
2742             } elsif ($base -> is_inf() || $base -> is_zero()) {
2743 36 100 100     73 return $x -> bnan(@r) if $x -> is_inf() || $x -> is_zero();
2744 15         49 return $x -> bzero(@r);
2745             } elsif ($base -> is_negative()) { # -inf < base < 0
2746 12 100       27 return $x -> bzero(@r) if $x -> is_one(); # x = 1
2747 9 50       30 return $x -> bone('+', @r) if $x == $base; # x = base
2748             # we can't handle these cases, so upgrade, if we can
2749 9 50       26 return $upgrade -> blog($x, $base, @r) if defined $upgrade;
2750 9         27 return $x -> bnan(@r);
2751             }
2752 100 100       336 return $x -> bone(@r) if $x == $base; # 0 < base && 0 < x < inf
2753             }
2754              
2755             # We now know that the base is either undefined or >= 2 and finite.
2756              
2757 127 100       352 if ($x -> is_inf()) { # x = +/-inf
    100          
    100          
    100          
2758 15         56 return $x -> binf('+', @r);
2759             } elsif ($x -> is_neg()) { # -inf < x < 0
2760 6 50       45 return $upgrade -> blog($x, $base, @r) if defined $upgrade;
2761 6         24 return $x -> bnan(@r);
2762             } elsif ($x -> is_one()) { # x = 1
2763 9         41 return $x -> bzero(@r);
2764             } elsif ($x -> is_zero()) { # x = 0
2765 6         45 return $x -> binf('-', @r);
2766             }
2767              
2768             # At this point we are done handling all exception cases and trivial cases.
2769              
2770 91 100       306 return $upgrade -> blog($x, $base, @r) if defined $upgrade;
2771              
2772             # fix for bug #24969:
2773             # the default base is e (Euler's number) which is not an integer
2774 89 100       219 if (!defined $base) {
2775 15         122 require Math::BigFloat;
2776              
2777             # disable upgrading and downgrading
2778              
2779 15         73 my $upg = Math::BigFloat -> upgrade();
2780 15         87 my $dng = Math::BigFloat -> downgrade();
2781 15         63 Math::BigFloat -> upgrade(undef);
2782 15         54 Math::BigFloat -> downgrade(undef);
2783              
2784 15         84 my $u = Math::BigFloat -> blog($x) -> as_int();
2785              
2786             # reset upgrading and downgrading
2787              
2788 15         113 Math::BigFloat -> upgrade($upg);
2789 15         68 Math::BigFloat -> downgrade($dng);
2790              
2791             # modify $x in place
2792              
2793 15         92 $x->{value} = $u->{value};
2794 15         49 $x->{sign} = $u->{sign};
2795              
2796 15         54 return $x -> round(@r);
2797             }
2798              
2799 74         228 my ($rc) = $LIB -> _log_int($x->{value}, $base->{value});
2800 74 50       176 return $x -> bnan(@r) unless defined $rc; # not possible to take log?
2801 74         132 $x->{value} = $rc;
2802 74         184 $x = $x -> round(@r);
2803             }
2804              
2805             sub bexp {
2806             # Calculate e ** $x (Euler's number to the power of X), truncated to
2807             # an integer value.
2808 15 50   15 1 231 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2809              
2810 15 50       67 return $x if $x->modify('bexp');
2811              
2812             # inf, -inf, NaN, <0 => NaN
2813 15 100       81 return $x -> bnan(@r) if $x->{sign} eq 'NaN';
2814 12 50       57 return $x -> bone(@r) if $x->is_zero();
2815 12 100       66 return $x -> round(@r) if $x->{sign} eq '+inf';
2816 9 50       45 return $x -> bzero(@r) if $x->{sign} eq '-inf';
2817              
2818 9 50       29 return $upgrade -> bexp($x, @r) if defined $upgrade;
2819              
2820 9         5772 require Math::BigFloat;
2821 9         52 my $tmp = Math::BigFloat -> bexp($x, @r) -> as_int();
2822 9         90 $x->{value} = $tmp->{value};
2823 9         37 return $x -> round(@r);
2824             }
2825              
2826             sub bnok {
2827             # Calculate n over k (binomial coefficient or "choose" function) as
2828             # integer.
2829              
2830             # Set up parameters.
2831 93 50 33 93 1 985 my ($class, $n, $k, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2832             ? (ref($_[0]), @_)
2833             : objectify(2, @_);
2834              
2835 93 50       236 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2836              
2837 93 50       287 return $n if $n->modify('bnok');
2838              
2839             # All cases where at least one argument is NaN.
2840              
2841 93 100 100     385 return $n->bnan(@r) if $n->{sign} eq 'NaN' || $k->{sign} eq 'NaN';
2842              
2843             # All cases where at least one argument is +/-inf.
2844              
2845 84 100       206 if ($n -> is_inf()) {
    50          
2846 7 50       49 if ($k -> is_inf()) { # bnok(+/-inf,+/-inf)
    50          
    50          
2847 0         0 return $n -> bnan(@r);
2848             } elsif ($k -> is_neg()) { # bnok(+/-inf,k), k < 0
2849 0         0 return $n -> bzero(@r);
2850             } elsif ($k -> is_zero()) { # bnok(+/-inf,k), k = 0
2851 0         0 return $n -> bone(@r);
2852             } else {
2853 7 50       54 if ($n -> is_inf("+", @r)) { # bnok(+inf,k), 0 < k < +inf
2854 7         50 return $n -> binf("+");
2855             } else { # bnok(-inf,k), k > 0
2856 0 0       0 my $sign = $k -> is_even() ? "+" : "-";
2857 0         0 return $n -> binf($sign, @r);
2858             }
2859             }
2860             }
2861              
2862             elsif ($k -> is_inf()) { # bnok(n,+/-inf), -inf <= n <= inf
2863 0         0 return $n -> bnan(@r);
2864             }
2865              
2866             # At this point, both n and k are real numbers.
2867              
2868 77 50 0     233 return $upgrade -> bnok($n, $k, @r)
      33        
2869             if defined($upgrade) && (!$n -> isa(__PACKAGE__) ||
2870             !$k -> isa(__PACKAGE__));
2871              
2872 77         127 my $sign = 1;
2873              
2874 77 50       243 if ($n >= 0) {
2875 77 100 100     217 if ($k < 0 || $k > $n) {
2876 21         99 return $n -> bzero(@r);
2877             }
2878             } else {
2879              
2880 0 0       0 if ($k >= 0) {
    0          
2881              
2882             # n < 0 and k >= 0: bnok(n,k) = (-1)^k * bnok(-n+k-1,k)
2883              
2884 0         0 $sign = (-1) ** $k;
2885 0         0 $n = $n -> bneg() -> badd($k) -> bdec();
2886              
2887             } elsif ($k <= $n) {
2888              
2889             # n < 0 and k <= n: bnok(n,k) = (-1)^(n-k) * bnok(-k-1,n-k)
2890              
2891 0         0 $sign = (-1) ** ($n - $k);
2892 0         0 my $x0 = $n -> copy();
2893 0         0 $n = $n -> bone() -> badd($k) -> bneg();
2894 0         0 $k = $k -> copy();
2895 0         0 $k = $k -> bneg() -> badd($x0);
2896              
2897             } else {
2898              
2899             # n < 0 and n < k < 0:
2900              
2901 0         0 return $n -> bzero(@r);
2902             }
2903             }
2904              
2905 56         257 $n->{value} = $LIB->_nok($n->{value}, $k->{value});
2906 56 50       156 $n = $n -> bneg() if $sign == -1;
2907              
2908 56         143 $n -> round(@r);
2909             }
2910              
2911             sub buparrow {
2912 0     0 1 0 my $a = shift;
2913 0         0 my $y = $a -> uparrow(@_);
2914 0         0 $a -> {value} = $y -> {value};
2915 0         0 return $a;
2916             }
2917              
2918             sub uparrow {
2919             # Knuth's up-arrow notation buparrow(a, n, b)
2920             #
2921             # The following is a simple, recursive implementation of the up-arrow
2922             # notation, just to show the idea. Such implementations cause "Deep
2923             # recursion on subroutine ..." warnings, so we use a faster, non-recursive
2924             # algorithm below with @_ as a stack.
2925             #
2926             # sub buparrow {
2927             # my ($a, $n, $b) = @_;
2928             # return $a ** $b if $n == 1;
2929             # return $a * $b if $n == 0;
2930             # return 1 if $b == 0;
2931             # return buparrow($a, $n - 1, buparrow($a, $n, $b - 1));
2932             # }
2933              
2934 0     0 1 0 my ($a, $b, $n) = @_;
2935 0         0 my $class = ref $a;
2936 0 0       0 croak("a must be non-negative") if $a < 0;
2937 0 0       0 croak("n must be non-negative") if $n < 0;
2938 0 0       0 croak("b must be non-negative") if $b < 0;
2939              
2940 0         0 while (@_ >= 3) {
2941              
2942             # return $a ** $b if $n == 1;
2943              
2944 0 0       0 if ($_[-2] == 1) {
2945 0         0 my ($a, $n, $b) = splice @_, -3;
2946 0         0 push @_, $a ** $b;
2947 0         0 next;
2948             }
2949              
2950             # return $a * $b if $n == 0;
2951              
2952 0 0       0 if ($_[-2] == 0) {
2953 0         0 my ($a, $n, $b) = splice @_, -3;
2954 0         0 push @_, $a * $b;
2955 0         0 next;
2956             }
2957              
2958             # return 1 if $b == 0;
2959              
2960 0 0       0 if ($_[-1] == 0) {
2961 0         0 splice @_, -3;
2962 0         0 push @_, $class -> bone();
2963 0         0 next;
2964             }
2965              
2966             # return buparrow($a, $n - 1, buparrow($a, $n, $b - 1));
2967              
2968 0         0 my ($a, $n, $b) = splice @_, -3;
2969 0         0 push @_, ($a, $n - 1,
2970             $a, $n, $b - 1);
2971              
2972             }
2973              
2974 0         0 pop @_;
2975             }
2976              
2977             sub backermann {
2978 0     0 1 0 my $m = shift;
2979 0         0 my $y = $m -> ackermann(@_);
2980 0         0 $m -> {value} = $y -> {value};
2981 0         0 return $m;
2982             }
2983              
2984             sub ackermann {
2985             # Ackermann's function ackermann(m, n)
2986             #
2987             # The following is a simple, recursive implementation of the ackermann
2988             # function, just to show the idea. Such implementations cause "Deep
2989             # recursion on subroutine ..." warnings, so we use a faster, non-recursive
2990             # algorithm below with @_ as a stack.
2991             #
2992             # sub ackermann {
2993             # my ($m, $n) = @_;
2994             # return $n + 1 if $m == 0;
2995             # return ackermann($m - 1, 1) if $m > 0 && $n == 0;
2996             # return ackermann($m - 1, ackermann($m, $n - 1) if $m > 0 && $n > 0;
2997             # }
2998              
2999 0     0 1 0 my ($m, $n) = @_;
3000 0         0 my $class = ref $m;
3001 0 0       0 croak("m must be non-negative") if $m < 0;
3002 0 0       0 croak("n must be non-negative") if $n < 0;
3003              
3004 0         0 my $two = $class -> new("2");
3005 0         0 my $three = $class -> new("3");
3006 0         0 my $thirteen = $class -> new("13");
3007              
3008 0         0 $n = pop;
3009 0 0       0 $n = $class -> new($n) unless ref($n);
3010 0         0 while (@_) {
3011 0         0 my $m = pop;
3012 0 0       0 if ($m > $three) {
    0          
    0          
    0          
3013 0         0 push @_, (--$m) x $n;
3014 0         0 while (--$m >= $three) {
3015 0         0 push @_, $m;
3016             }
3017 0         0 $n = $thirteen;
3018             } elsif ($m == $three) {
3019 0         0 $n = $class -> bone() -> blsft($n + $three) -> bsub($three);
3020             } elsif ($m == $two) {
3021 0         0 $n = $n -> bmul($two) -> badd($three);
3022             } elsif ($m >= 0) {
3023 0         0 $n = $n -> badd($m) -> binc();
3024             } else {
3025 0         0 die "negative m!";
3026             }
3027             }
3028 0         0 $n;
3029             }
3030              
3031             sub bsin {
3032             # Calculate sin(x) to N digits. Unless upgrading is in effect, returns the
3033             # result truncated to an integer.
3034 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3035              
3036 0 0       0 return $x if $x->modify('bsin');
3037              
3038 0 0       0 return $x->bnan(@r) if $x->{sign} !~ /^[+-]\z/; # -inf +inf or NaN => NaN
3039 0 0       0 return $x->bzero(@r) if $x->is_zero();
3040              
3041 0 0       0 return $upgrade -> bsin($x, @r) if defined $upgrade;
3042              
3043 0         0 require Math::BigFloat;
3044             # calculate the result and truncate it to integer
3045 0         0 my $t = Math::BigFloat->new($x)->bsin(@r)->as_int();
3046              
3047 0 0       0 $x = $x->bone(@r) if $t->is_one();
3048 0 0       0 $x = $x->bzero(@r) if $t->is_zero();
3049 0         0 $x->round(@r);
3050             }
3051              
3052             sub bcos {
3053             # Calculate cos(x) to N digits. Unless upgrading is in effect, returns the
3054             # result truncated to an integer.
3055 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3056              
3057 0 0       0 return $x if $x->modify('bcos');
3058              
3059 0 0       0 return $x->bnan(@r) if $x->{sign} !~ /^[+-]\z/; # -inf +inf or NaN => NaN
3060 0 0       0 return $x->bone(@r) if $x->is_zero();
3061              
3062 0 0       0 return $upgrade -> bcos($x, @r) if defined $upgrade;
3063              
3064 0         0 require Math::BigFloat;
3065 0         0 my $tmp = Math::BigFloat -> bcos($x, @r) -> as_int();
3066 0         0 $x->{value} = $tmp->{value};
3067 0         0 return $x -> round(@r);
3068             }
3069              
3070             sub batan {
3071             # Calculate arctan(x) to N digits. Unless upgrading is in effect, returns
3072             # the result truncated to an integer.
3073 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3074              
3075 0 0       0 return $x if $x->modify('batan');
3076              
3077 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
3078 0 0       0 return $x -> bzero(@r) if $x -> is_zero();
3079              
3080 0 0       0 return $upgrade -> batan($x, @r) if defined $upgrade;
3081              
3082 0 0       0 return $x -> bone("+", @r) if $x -> bgt("1");
3083 0 0       0 return $x -> bone("-", @r) if $x -> blt("-1");
3084              
3085 0         0 $x -> bzero(@r);
3086             }
3087              
3088             sub batan2 {
3089             # calculate arcus tangens of ($y/$x)
3090              
3091 84 50 33 84 1 1456 my ($class, $y, $x, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3092             ? (ref($_[0]), @_) : objectify(2, @_);
3093              
3094 84 50       298 return $y if $y->modify('batan2');
3095              
3096 84 100 100     571 return $y->bnan() if ($y->{sign} eq $nan) || ($x->{sign} eq $nan);
3097              
3098 75 50       191 return $upgrade->batan2($y, $x, @r) if defined $upgrade;
3099              
3100             # Y X
3101             # != 0 -inf result is +- pi
3102 75 100 100     204 if ($x->is_inf() || $y->is_inf()) {
3103 30 100       68 if ($y->is_inf()) {
3104 18 100       57 if ($x->{sign} eq '-inf') {
    100          
3105             # calculate 3 pi/4 => 2.3.. => 2
3106 6         35 $y = $y->bone(substr($y->{sign}, 0, 1));
3107 6         35 $y = $y->bmul($class->new(2));
3108             } elsif ($x->{sign} eq '+inf') {
3109             # calculate pi/4 => 0.7 => 0
3110 6         20 $y = $y->bzero();
3111             } else {
3112             # calculate pi/2 => 1.5 => 1
3113 6         31 $y = $y->bone(substr($y->{sign}, 0, 1));
3114             }
3115             } else {
3116 12 100       48 if ($x->{sign} eq '+inf') {
3117             # calculate pi/4 => 0.7 => 0
3118 3         22 $y = $y->bzero();
3119             } else {
3120             # PI => 3.1415.. => 3
3121 9         35 $y = $y->bone(substr($y->{sign}, 0, 1));
3122 9         47 $y = $y->bmul($class->new(3));
3123             }
3124             }
3125 30         366 return $y;
3126             }
3127              
3128 45         257 require Math::BigFloat;
3129 45         203 my $r = Math::BigFloat->new($y)
3130             ->batan2(Math::BigFloat->new($x), @r)
3131             ->as_int();
3132              
3133 45         357 $x->{value} = $r->{value};
3134 45         124 $x->{sign} = $r->{sign};
3135              
3136 45         120 $x->round(@r);
3137             }
3138              
3139             sub bsqrt {
3140             # calculate square root of $x
3141 523 100   523 1 5140 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3142              
3143 523 50       1702 return $x if $x->modify('bsqrt');
3144              
3145 523 100       2064 return $x->bnan(@r) if $x->{sign} !~ /^\+/; # -x or -inf or NaN => NaN
3146 507 100       1364 return $x->round(@r) if $x->{sign} eq '+inf'; # sqrt(+inf) == inf
3147              
3148 503 100       1117 return $upgrade->bsqrt($x, @r) if defined $upgrade;
3149              
3150 481         1670 $x->{value} = $LIB->_sqrt($x->{value});
3151 481         1386 $x->round(@r);
3152             }
3153              
3154             sub broot {
3155             # calculate $y'th root of $x
3156              
3157             # set up parameters
3158              
3159 174 100 66 174 1 2465 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3160             ? (ref($_[0]), @_) : objectify(2, @_);
3161              
3162 174 50       401 $y = $class->new(2) unless defined $y;
3163              
3164 174 50       582 return $x if $x->modify('broot');
3165              
3166             # NaN handling: $x ** 1/0, x or y NaN, or y inf/-inf or y == 0
3167             return $x->bnan(@r) if $x->{sign} !~ /^\+/ || $y->is_zero() ||
3168 174 100 100     866 $y->{sign} !~ /^\+$/;
      100        
3169              
3170 99 100 100     252 return $x->round(@r)
      100        
      100        
3171             if $x->is_zero() || $x->is_one() || $x->is_inf() || $y->is_one();
3172              
3173 87 100       251 return $upgrade->broot($x, $y, @r) if defined $upgrade;
3174              
3175 85         378 $x->{value} = $LIB->_root($x->{value}, $y->{value});
3176 85         263 $x->round(@r);
3177             }
3178              
3179             sub bfac {
3180             # (BINT or num_str, BINT or num_str) return BINT
3181             # compute factorial number from $x, modify $x in place
3182 81 50   81 1 850 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3183              
3184 81 100 66     456 return $x if $x->modify('bfac') || $x->{sign} eq '+inf'; # inf => inf
3185              
3186 78 100       203 return $x->bnan(@r) if $x->{sign} ne '+'; # NaN, <0 => NaN
3187              
3188 69 50 33     194 return $upgrade -> bfac($x, @r)
3189             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3190              
3191 69         241 $x->{value} = $LIB->_fac($x->{value});
3192 69         188 $x->round(@r);
3193             }
3194              
3195             sub bdfac {
3196             # compute double factorial, modify $x in place
3197 54 50   54 1 699 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3198              
3199 54 100 66     307 return $x if $x->modify('bdfac') || $x->{sign} eq '+inf'; # inf => inf
3200              
3201 51 100 100     119 return $x->bnan(@r) if $x->is_nan() || $x <= -2;
3202 42 100       355 return $x->bone(@r) if $x <= 1;
3203              
3204 33 50 33     112 return $upgrade -> bdfac($x, @r)
3205             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3206              
3207 33 50       196 croak("bdfac() requires a newer version of the $LIB library.")
3208             unless $LIB->can('_dfac');
3209              
3210 33         115 $x->{value} = $LIB->_dfac($x->{value});
3211 33         82 $x->round(@r);
3212             }
3213              
3214             sub btfac {
3215             # compute triple factorial, modify $x in place
3216 57 50   57 1 861 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3217              
3218 57 100 66     333 return $x if $x->modify('btfac') || $x->{sign} eq '+inf'; # inf => inf
3219              
3220 54 100       132 return $x->bnan(@r) if $x->is_nan();
3221              
3222 51 50 33     140 return $upgrade -> btfac($x, @r)
3223             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3224              
3225 51         132 my $k = $class -> new("3");
3226 51 100       217 return $x->bnan(@r) if $x <= -$k;
3227              
3228 45         208 my $one = $class -> bone();
3229 45 100       98 return $x->bone(@r) if $x <= $one;
3230              
3231 33         93 my $f = $x -> copy();
3232 33         109 while ($f -> bsub($k) > $one) {
3233 45         134 $x = $x -> bmul($f);
3234             }
3235 33         90 $x->round(@r);
3236             }
3237              
3238             sub bmfac {
3239             # compute multi-factorial
3240              
3241 270 50 33 270 1 3999 my ($class, $x, $k, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3242             ? (ref($_[0]), @_) : objectify(2, @_);
3243              
3244 270 100 66     1417 return $x if $x->modify('bmfac') || $x->{sign} eq '+inf';
3245 255 100 100     552 return $x->bnan(@r) if $x->is_nan() || $k->is_nan() || $k < 1 || $x <= -$k;
      100        
      100        
3246              
3247 198 50 33     718 return $upgrade -> bmfac($x, $k, @r)
3248             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3249              
3250 198         480 my $one = $class -> bone();
3251 198 100       456 return $x->bone(@r) if $x <= $one;
3252              
3253 138         334 my $f = $x -> copy();
3254 138         368 while ($f -> bsub($k) > $one) {
3255 213         649 $x = $x -> bmul($f);
3256             }
3257 138         365 $x->round(@r);
3258             }
3259              
3260             sub bfib {
3261             # compute Fibonacci number(s)
3262 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3263              
3264 0 0       0 croak("bfib() requires a newer version of the $LIB library.")
3265             unless $LIB->can('_fib');
3266              
3267 0 0       0 return $x if $x->modify('bfib');
3268              
3269 0 0 0     0 return $upgrade -> bfib($x, @r)
3270             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3271              
3272             # List context.
3273              
3274 0 0       0 if (wantarray) {
3275 0 0       0 return () if $x -> is_nan();
3276 0 0       0 croak("bfib() can't return an infinitely long list of numbers")
3277             if $x -> is_inf();
3278              
3279             # Use the backend library to compute the first $x Fibonacci numbers.
3280              
3281 0         0 my @values = $LIB->_fib($x->{value});
3282              
3283             # Make objects out of them. The last element in the array is the
3284             # invocand.
3285              
3286 0         0 for (my $i = 0 ; $i < $#values ; ++ $i) {
3287 0         0 my $fib = $class -> bzero();
3288 0         0 $fib -> {value} = $values[$i];
3289 0         0 $values[$i] = $fib;
3290             }
3291              
3292 0         0 $x -> {value} = $values[-1];
3293 0         0 $values[-1] = $x;
3294              
3295             # If negative, insert sign as appropriate.
3296              
3297 0 0       0 if ($x -> is_neg()) {
3298 0         0 for (my $i = 2 ; $i <= $#values ; $i += 2) {
3299 0         0 $values[$i]{sign} = '-';
3300             }
3301             }
3302              
3303 0         0 @values = map { $_ -> round(@r) } @values;
  0         0  
3304 0         0 return @values;
3305             }
3306              
3307             # Scalar context.
3308              
3309             else {
3310 0 0 0     0 return $x if $x->modify('bdfac') || $x -> is_inf('+');
3311 0 0 0     0 return $x->bnan() if $x -> is_nan() || $x -> is_inf('-');
3312              
3313 0 0 0     0 $x->{sign} = $x -> is_neg() && $x -> is_even() ? '-' : '+';
3314 0         0 $x->{value} = $LIB->_fib($x->{value});
3315 0         0 return $x->round(@r);
3316             }
3317             }
3318              
3319             sub blucas {
3320             # compute Lucas number(s)
3321 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3322              
3323 0 0       0 croak("blucas() requires a newer version of the $LIB library.")
3324             unless $LIB->can('_lucas');
3325              
3326 0 0       0 return $x if $x->modify('blucas');
3327              
3328 0 0 0     0 return $upgrade -> blucas($x, @r)
3329             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3330              
3331             # List context.
3332              
3333 0 0       0 if (wantarray) {
3334 0 0       0 return () if $x -> is_nan();
3335 0 0       0 croak("blucas() can't return an infinitely long list of numbers")
3336             if $x -> is_inf();
3337              
3338             # Use the backend library to compute the first $x Lucas numbers.
3339              
3340 0         0 my @values = $LIB->_lucas($x->{value});
3341              
3342             # Make objects out of them. The last element in the array is the
3343             # invocand.
3344              
3345 0         0 for (my $i = 0 ; $i < $#values ; ++ $i) {
3346 0         0 my $lucas = $class -> bzero();
3347 0         0 $lucas -> {value} = $values[$i];
3348 0         0 $values[$i] = $lucas;
3349             }
3350              
3351 0         0 $x -> {value} = $values[-1];
3352 0         0 $values[-1] = $x;
3353              
3354             # If negative, insert sign as appropriate.
3355              
3356 0 0       0 if ($x -> is_neg()) {
3357 0         0 for (my $i = 2 ; $i <= $#values ; $i += 2) {
3358 0         0 $values[$i]{sign} = '-';
3359             }
3360             }
3361              
3362 0         0 @values = map { $_ -> round(@r) } @values;
  0         0  
3363 0         0 return @values;
3364             }
3365              
3366             # Scalar context.
3367              
3368             else {
3369 0 0       0 return $x if $x -> is_inf('+');
3370 0 0 0     0 return $x->bnan() if $x -> is_nan() || $x -> is_inf('-');
3371              
3372 0 0 0     0 $x->{sign} = $x -> is_neg() && $x -> is_even() ? '-' : '+';
3373 0         0 $x->{value} = $LIB->_lucas($x->{value});
3374 0         0 return $x->round(@r);
3375             }
3376             }
3377              
3378             sub blsft {
3379             # (BINT or num_str, BINT or num_str) return BINT
3380             # compute $x << $y, base $n
3381              
3382 62     62 1 533 my ($class, $x, $y, $b, @r);
3383              
3384             # Objectify the base only when it is defined, since an undefined base, as
3385             # in $x->blsft(3) or $x->blog(3, undef) means use the default base 2.
3386              
3387 62 100 66     273 if (!ref($_[0]) && $_[0] =~ /^[A-Za-z]|::/) {
3388             # E.g., Math::BigInt->blog(256, 5, 2)
3389 12 50       93 ($class, $x, $y, $b, @r) =
3390             defined $_[3] ? objectify(3, @_) : objectify(2, @_);
3391             } else {
3392             # E.g., Math::BigInt::blog(256, 5, 2) or $x->blog(5, 2)
3393 50 100       194 ($class, $x, $y, $b, @r) =
3394             defined $_[2] ? objectify(3, @_) : objectify(2, @_);
3395             }
3396              
3397 62 50       320 return $x if $x -> modify('blsft');
3398              
3399 62 100       162 $b = 2 unless defined $b;
3400 62 100       242 $b = $class -> new($b) unless defined(blessed($b));
3401              
3402 62 50 33     268 return $upgrade -> blsft($x, $y, $b, @r)
      66        
3403             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
3404             !$y -> isa(__PACKAGE__) ||
3405             !$b -> isa(__PACKAGE__));
3406              
3407 62 50 33     155 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan() || $b -> is_nan();
      33        
3408              
3409             # blsft($x, -$y, $b) = brsft($x, $y, $b)
3410              
3411 62 100       159 return $x -> brsft($y -> copy() -> bneg(), $b, @r) if $y -> is_neg();
3412              
3413 58         175 return $x -> bmul($b -> bpow($y));
3414              
3415             # Base $b = 1 changes nothing, not even when $b = Inf. Shifting zero places
3416             # ($y = 0) doesn't change anything either.
3417 0 0 0     0 return $x -> bround(@r) if $b -> is_one("+") || $y -> is_zero();
3418              
3419             # Shifting infinitely far to the left.
3420 0 0       0 if ($y -> is_inf("+")) {
3421 0 0       0 return $x -> binf("+", @r) if $x -> is_pos();
3422 0 0       0 return $x -> binf("-", @r) if $x -> is_neg();
3423 0         0 return $x -> bnan(@r); # Inf * 0 = NaN
3424             }
3425              
3426             # At this point we know that $b > 1, so we are essentially computing 0 *
3427             # Inf = NaN.
3428 0 0 0     0 return $x -> bnan(@r) if $x -> is_zero() && $y -> is_inf("+");
3429              
3430             # Handle trivial zero case.
3431 0 0       0 return $x -> bzero(@r) if $x -> is_zero();
3432              
3433 0 0       0 return $x -> binf("+", @r) if $y -> is_inf("+");
3434 0 0       0 return $x -> bzero(@r) if $x -> is_zero();
3435              
3436             # While some of the libraries support an arbitrarily large base, not all of
3437             # them do, so rather than returning an incorrect result in those cases,
3438             # disallow bases that don't work with all libraries.
3439              
3440 0         0 my $uintmax = ~0;
3441 0 0       0 if ($x -> bcmp($uintmax) > 0) {
3442 0         0 $x = $x -> bmul($b -> bpow($y));
3443             } else {
3444 0         0 $b = $b -> numify();
3445 0         0 $x -> {value} = $LIB -> _lsft($x -> {value}, $y -> {value}, $b);
3446             }
3447 0         0 $x -> round(@r);
3448             }
3449              
3450             sub brsft {
3451             # (BINT or num_str, BINT or num_str) return BINT
3452             # compute $x >> $y, base $n
3453              
3454 134     134 1 1348 my ($class, $x, $y, $b, @r) = (ref($_[0]), @_);
3455              
3456             # Objectify the base only when it is defined, since an undefined base, as
3457             # in $x->blsft(3) or $x->blog(3, undef) means use the default base 2.
3458              
3459 134 100 66     503 if (!ref($_[0]) && $_[0] =~ /^[A-Za-z]|::/) {
3460             # E.g., Math::BigInt->blog(256, 5, 2)
3461 12 50       72 ($class, $x, $y, $b, @r) =
3462             defined $_[3] ? objectify(3, @_) : objectify(2, @_);
3463             } else {
3464             # E.g., Math::BigInt::blog(256, 5, 2) or $x->blog(5, 2)
3465 122 100       395 ($class, $x, $y, $b, @r) =
3466             defined $_[2] ? objectify(3, @_) : objectify(2, @_);
3467             }
3468              
3469 134 50       519 return $x if $x -> modify('brsft');
3470              
3471 134 100       298 $b = 2 unless defined $b;
3472 134 100       1461 $b = $class -> new($b) unless defined(blessed($b));
3473              
3474 134 50 33     505 return $upgrade -> brsft($x, $y, $b, @r)
      66        
3475             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
3476             !$y -> isa(__PACKAGE__) ||
3477             !$b -> isa(__PACKAGE__));
3478              
3479 134 50 33     313 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan() || $b -> is_nan();
      33        
3480              
3481             # brsft($x, -$y, $b) = blsft($x, $y, $b)
3482              
3483 134 100       353 return $x -> blsft($y -> copy() -> bneg(), $b, @r) if $y -> is_neg();
3484              
3485 130 100       298 return $x -> round(@r) if $y -> is_zero();
3486 122 50       268 return $x -> bzero(@r) if $x -> is_zero();
3487              
3488             # Shifting right by a positive amount might lead to a non-integer result.
3489              
3490 122 100 66     339 return $upgrade -> brsft($x, $y, $b, @r)
3491             if defined($upgrade) && $y -> is_pos();
3492              
3493             # This only works for negative numbers when shifting in base 2.
3494 111 100 66     201 if ($x -> is_neg() && $b -> bcmp("2") == 0) {
3495 57 100       149 return $x -> round(@r) if $x -> is_one('-'); # -1 => -1
3496             # Although this is O(N*N) in Math::BigInt::Calc->_as_bin(), it is O(N)
3497             # in Pari et al., but perhaps there is a better emulation for two's
3498             # complement shift ... if $y != 1, we must simulate it by doing:
3499             # convert to bin, flip all bits, shift, and be done
3500 54         157 $x = $x -> binc(); # -3 => -2
3501 54         164 my $bin = $x -> to_bin(); # convert to string
3502 54         231 $bin =~ s/^-//; # strip leading minus
3503 54         115 $bin =~ tr/10/01/; # flip bits
3504 54         85 my $nbits = CORE::length($bin);
3505 54 100       155 return $x -> bone("-", @r) if $y >= $nbits;
3506 51         166 $bin = substr $bin, 0, $nbits - $y; # keep most significant bits
3507 51         171 $bin = '1' . $bin; # prepend one dummy '1'
3508 51         124 $bin =~ tr/10/01/; # flip bits back
3509 51         175 my $res = $class -> from_bin($bin); # convert back from string
3510 51         159 $res = $res -> binc(); # remember to increment
3511 51         142 $x -> {value} = $res -> {value}; # take over value
3512 51         96 return $x -> round(@r);
3513             }
3514              
3515             # While some of the libraries support an arbitrarily large base, not all of
3516             # them do, so rather than returning an incorrect result in those cases, use
3517             # division.
3518              
3519 54         103 my $uintmax = ~0;
3520 54 50 33     158 if ($x -> bcmp($uintmax) > 0 || $x -> is_neg()) {
3521 0         0 $x = $x -> bdiv($b -> bpow($y));
3522             } else {
3523 54         540 $b = $b -> numify();
3524 54         291 $x -> {value} = $LIB -> _rsft($x -> {value}, $y -> {value}, $b);
3525             }
3526              
3527 54         169 return $x -> round(@r);
3528             }
3529              
3530             ###############################################################################
3531             # Bitwise methods
3532             ###############################################################################
3533              
3534             # Bitwise left shift.
3535              
3536             sub bblsft {
3537             # We don't call objectify(), because the bitwise methods should not
3538             # upgrade/downgrade, even when upgrading/downgrading is enabled.
3539              
3540 35     35 1 79 my ($class, $x, $y, @r);
3541              
3542             # $x -> bblsft($y)
3543              
3544 35 100       116 if (ref($_[0])) {
3545 27         74 ($class, $x, $y, @r) = (ref($_[0]), @_);
3546 27 50 33     216 $y = $y -> as_int()
      33        
3547             if ref($y) && !$y -> isa(__PACKAGE__) && $y -> can('as_int');
3548 27 50       80 $y = $class -> new(int($y)) unless ref($y);
3549             }
3550              
3551             # $class -> bblsft($x, $y)
3552              
3553             else {
3554 8         23 ($class, $x, $y, @r) = @_;
3555 8         21 for ($x, $y) {
3556 16 50 33     70 $_ = $_ -> as_int()
      33        
3557             if ref($_) && !$_ -> isa(__PACKAGE__) && $_ -> can('as_int');
3558 16 50       62 $_ = $class -> new(int($_)) unless ref($_);
3559             }
3560             }
3561              
3562 35 50       135 return $x if $x -> modify('bblsft');
3563              
3564 35 100 66     103 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
3565              
3566             # bblsft($x, -$y) = bbrsft($x, $y)
3567              
3568 31 100       117 return $x -> bbrsft($y -> copy() -> bneg()) if $y -> is_neg();
3569              
3570             # Shifting infinitely far to the left.
3571              
3572 27 50       89 if ($y -> is_inf("+")) {
3573 0 0       0 return $x -> binf("+", @r) if $x -> is_pos();
3574 0 0       0 return $x -> binf("-", @r) if $x -> is_neg();
3575 0         0 return $x -> bnan(@r);
3576             }
3577              
3578             # These cases change nothing.
3579              
3580 27 50 33     155 return $x -> round(@r) if $x -> is_zero() || $x -> is_inf() ||
      33        
3581             $y -> is_zero();
3582              
3583 27         154 $x -> {value} = $LIB -> _lsft($x -> {value}, $y -> {value}, 2);
3584 27         118 $x -> round(@r);
3585             }
3586              
3587             # Bitwise right shift.
3588              
3589             sub bbrsft {
3590             # We don't call objectify(), because the bitwise methods should not
3591             # upgrade/downgrade, even when upgrading/downgrading is enabled.
3592              
3593 35     35 1 81 my ($class, $x, $y, @r);
3594              
3595             # $x -> bblsft($y)
3596              
3597 35 100       96 if (ref($_[0])) {
3598 27         75 ($class, $x, $y, @r) = (ref($_[0]), @_);
3599 27 50 33     172 $y = $y -> as_int()
      33        
3600             if ref($y) && !$y -> isa(__PACKAGE__) && $y -> can('as_int');
3601 27 50       73 $y = $class -> new(int($y)) unless ref($y);
3602             }
3603              
3604             # $class -> bblsft($x, $y)
3605              
3606             else {
3607 8         22 ($class, $x, $y, @r) = @_;
3608 8         22 for ($x, $y) {
3609 16 50 33     68 $_ = $_ -> as_int()
      33        
3610             if ref($_) && !$_ -> isa(__PACKAGE__) && $_ -> can('as_int');
3611 16 50       85 $_ = $class -> new(int($_)) unless ref($_);
3612             }
3613             }
3614              
3615 35 50       130 return $x if $x -> modify('bbrsft');
3616              
3617 35 100 66     120 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
3618              
3619             # bbrsft($x, -$y) = bblsft($x, $y)
3620              
3621 31 100       116 return $x -> bblsft($y -> copy() -> bneg()) if $y -> is_neg();
3622              
3623             # Shifting infinitely far to the right.
3624              
3625 27 50       101 if ($y -> is_inf("+")) {
3626 0 0       0 return $x -> bnan(@r) if $x -> is_inf();
3627 0 0       0 return $x -> bone("-", @r) if $x -> is_neg();
3628 0         0 return $x -> bzero(@r);
3629             }
3630              
3631             # These cases change nothing.
3632              
3633 27 50 33     144 return $x -> round(@r) if $x -> is_zero() || $x -> is_inf() ||
      33        
3634             $y -> is_zero();
3635              
3636             # At this point, $x is either positive or negative, not zero.
3637              
3638 27 50       140 if ($x -> is_pos()) {
3639 27         152 $x -> {value} = $LIB -> _rsft($x -> {value}, $y -> {value}, 2);
3640             } else {
3641 0         0 my $n = $x -> {value};
3642 0         0 my $d = $LIB -> _pow($LIB -> _new("2"), $y -> {value});
3643 0         0 my ($p, $q) = $LIB -> _div($n, $d);
3644 0 0       0 $p = $LIB -> _inc($p) unless $LIB -> _is_zero($q);
3645 0         0 $x -> {value} = $p;
3646             }
3647              
3648 27         130 $x -> round(@r);
3649             }
3650              
3651             sub band {
3652             #(BINT or num_str, BINT or num_str) return BINT
3653             # compute x & y
3654              
3655 175 100 66 175 1 1324 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3656             ? (ref($_[0]), @_) : objectify(2, @_);
3657              
3658 175 50       897 return $x if $x->modify('band');
3659              
3660 175 100 66     542 return $upgrade -> band($x, $y, @r)
      100        
3661             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
3662             !$y -> isa(__PACKAGE__));
3663              
3664 174         292 $r[3] = $y; # no push!
3665              
3666 174 100 100     1020 return $x->bnan(@r) if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/;
3667              
3668 162 100 100     617 if ($x->{sign} eq '+' && $y->{sign} eq '+') {
3669 129         481 $x->{value} = $LIB->_and($x->{value}, $y->{value});
3670             } else {
3671             ($x->{value}, $x->{sign}) = $LIB->_sand($x->{value}, $x->{sign},
3672 33         155 $y->{value}, $y->{sign});
3673             }
3674 162         488 return $x->round(@r);
3675             }
3676              
3677             sub bior {
3678             #(BINT or num_str, BINT or num_str) return BINT
3679             # compute x | y
3680              
3681 236 100 66 236 1 1615 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3682             ? (ref($_[0]), @_) : objectify(2, @_);
3683              
3684 236 50       788 return $x if $x->modify('bior');
3685              
3686 236 100 66     772 return $upgrade -> bior($x, $y, @r)
      100        
3687             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
3688             !$y -> isa(__PACKAGE__));
3689              
3690 235         447 $r[3] = $y; # no push!
3691              
3692 235 100 100     1337 return $x->bnan() if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/);
3693              
3694 223 100 100     844 if ($x->{sign} eq '+' && $y->{sign} eq '+') {
3695 188         652 $x->{value} = $LIB->_or($x->{value}, $y->{value});
3696             } else {
3697             ($x->{value}, $x->{sign}) = $LIB->_sor($x->{value}, $x->{sign},
3698 35         178 $y->{value}, $y->{sign});
3699             }
3700 223         632 return $x->round(@r);
3701             }
3702              
3703             sub bxor {
3704             #(BINT or num_str, BINT or num_str) return BINT
3705             # compute x ^ y
3706              
3707 246 100 66 246 1 1669 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3708             ? (ref($_[0]), @_) : objectify(2, @_);
3709              
3710 246 50       808 return $x if $x->modify('bxor');
3711              
3712 246 100 66     817 return $upgrade -> bxor($x, $y, @r)
      100        
3713             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
3714             !$y -> isa(__PACKAGE__));
3715              
3716 245         412 $r[3] = $y; # no push!
3717              
3718 245 100 100     1417 return $x->bnan(@r) if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/;
3719              
3720 233 100 100     825 if ($x->{sign} eq '+' && $y->{sign} eq '+') {
3721 193         663 $x->{value} = $LIB->_xor($x->{value}, $y->{value});
3722             } else {
3723             ($x->{value}, $x->{sign}) = $LIB->_sxor($x->{value}, $x->{sign},
3724 40         213 $y->{value}, $y->{sign});
3725             }
3726 233         672 return $x->round(@r);
3727             }
3728              
3729             sub bnot {
3730             # (num_str or BINT) return BINT
3731             # represent ~x as twos-complement number
3732 39 50   39 1 419 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3733              
3734 39 50       142 return $x if $x->modify('bnot');
3735              
3736 39 50 66     132 return $upgrade -> bnot($x, @r)
3737             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3738              
3739 39         119 $x -> binc() -> bneg(@r);
3740             }
3741              
3742             ###############################################################################
3743             # Rounding methods
3744             ###############################################################################
3745              
3746             sub round {
3747             # Round $self according to given parameters, or given second argument's
3748             # parameters or global defaults
3749              
3750 71804 50   71804 1 232827 my ($class, $self, @args) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3751              
3752             # $x->round(undef, undef) signals no rounding
3753              
3754 71804 100 100     251001 if (@args >= 2 && @args <= 3 && !defined($args[0]) && !defined($args[1])) {
      100        
      100        
3755 3599         7438 $self->{_a} = undef;
3756 3599         5433 $self->{_p} = undef;
3757 3599         9082 return $self;
3758             }
3759              
3760 68205         152615 my ($a, $p, $r) = splice @args, 0, 3;
3761              
3762             # $a accuracy, if given by caller
3763             # $p precision, if given by caller
3764             # $r round_mode, if given by caller
3765             # @args all 'other' arguments (0 for unary, 1 for binary ops)
3766              
3767 68205 100       139844 if (defined $a) {
3768 304 50       1517 croak "accuracy must be a number, not '$a'"
3769             unless $a =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
3770             }
3771              
3772 68205 100       127513 if (defined $p) {
3773 92 50       516 croak "precision must be a number, not '$p'"
3774             unless $p =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
3775             }
3776              
3777             # now pick $a or $p, but only if we have got "arguments"
3778 68205 100       130914 if (!defined $a) {
3779 67901         122926 foreach ($self, @args) {
3780             # take the defined one, or if both defined, the one that is smaller
3781             $a = $_->{_a}
3782 108121 100 100     314441 if (defined $_->{_a}) && (!defined $a || $_->{_a} < $a);
      100        
3783             }
3784             }
3785 68205 100       126278 if (!defined $p) {
3786             # even if $a is defined, take $p, to signal error for both defined
3787 68113         107286 foreach ($self, @args) {
3788             # take the defined one, or if both defined, the one that is bigger
3789             # -2 > -3, and 3 > 2
3790             $p = $_->{_p}
3791 108356 100 66     230698 if (defined $_->{_p}) && (!defined $p || $_->{_p} > $p);
      66        
3792             }
3793             }
3794              
3795 51     51   640 no strict 'refs';
  51         176  
  51         411580  
3796              
3797             # if still none defined, use globals
3798 68205 100 100     193768 unless (defined $a || defined $p) {
3799 46880         62826 $a = ${"$class\::accuracy"};
  46880         144871  
3800 46880         63628 $p = ${"$class\::precision"};
  46880         99031  
3801             }
3802              
3803             # A == 0 is useless, so undef it to signal no rounding
3804 68205 100 100     169906 $a = undef if defined $a && $a == 0;
3805              
3806             # no rounding today?
3807 68205 100 100     284948 return $self unless defined $a || defined $p; # early out
3808              
3809             # set A and set P is an fatal error
3810 21363 100 100     60730 return $self->bnan() if defined $a && defined $p;
3811              
3812 21305 100       38234 $r = ${"$class\::round_mode"} unless defined $r;
  21244         74268  
3813 21305 50       81694 if ($r !~ /^(even|odd|[+-]inf|zero|trunc|common)$/) {
3814 0         0 croak("Unknown round mode '$r'");
3815             }
3816              
3817             # now round, by calling either bround or bfround:
3818 21305 100       40538 if (defined $a) {
3819             $self = $self->bround(int($a), $r)
3820 21140 100 100     108960 if !defined $self->{_a} || $self->{_a} >= $a;
3821             } else { # both can't be undefined due to early out
3822             $self = $self->bfround(int($p), $r)
3823 165 50 66     852 if !defined $self->{_p} || $self->{_p} <= $p;
3824             }
3825              
3826             # bround() or bfround() already called bnorm() if nec.
3827 21305         66014 $self;
3828             }
3829              
3830             sub bround {
3831             # accuracy: +$n preserve $n digits from left,
3832             # -$n preserve $n digits from right (f.i. for 0.1234 style in MBF)
3833             # no-op for $n == 0
3834             # and overwrite the rest with 0's, return normalized number
3835             # do not return $x->bnorm(), but $x
3836              
3837 26041 50   26041 1 83349 my ($class, $x, @a) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3838              
3839 26041         55330 my ($scale, $mode) = $x->_scale_a(@a);
3840 26041 100 66     112181 return $x if !defined $scale || $x->modify('bround'); # no-op
3841              
3842 26039 100 100     59252 if ($x->is_zero() || $scale == 0) {
3843 101 100 66     489 $x->{_a} = $scale if !defined $x->{_a} || $x->{_a} > $scale; # 3 > 2
3844 101         391 return $x;
3845             }
3846 25938 100       73830 return $x if $x->{sign} !~ /^[+-]$/; # inf, NaN
3847              
3848             # we have fewer digits than we want to scale to
3849 25926         59601 my $len = $x->length();
3850             # convert $scale to a scalar in case it is an object (put's a limit on the
3851             # number length, but this would already limited by memory constraints),
3852             # makes it faster
3853 25926 50       48905 $scale = $scale->numify() if ref ($scale);
3854              
3855             # scale < 0, but > -len (not >=!)
3856 25926 100 66     96689 if (($scale < 0 && $scale < -$len-1) || ($scale >= $len)) {
      66        
3857 194 100 66     895 $x->{_a} = $scale if !defined $x->{_a} || $x->{_a} > $scale; # 3 > 2
3858 194         631 return $x;
3859             }
3860              
3861             # count of 0's to pad, from left (+) or right (-): 9 - +6 => 3, or |-6| => 6
3862 25732         40611 my ($pad, $digit_round, $digit_after);
3863 25732         34475 $pad = $len - $scale;
3864 25732 100       47514 $pad = abs($scale-1) if $scale < 0;
3865              
3866             # do not use digit(), it is very costly for binary => decimal
3867             # getting the entire string is also costly, but we need to do it only once
3868 25732         66608 my $xs = $LIB->_str($x->{value});
3869 25732         42656 my $pl = -$pad-1;
3870              
3871             # pad: 123: 0 => -1, at 1 => -2, at 2 => -3, at 3 => -4
3872             # pad+1: 123: 0 => 0, at 1 => -1, at 2 => -2, at 3 => -3
3873 25732         38461 $digit_round = '0';
3874 25732 100       61284 $digit_round = substr($xs, $pl, 1) if $pad <= $len;
3875 25732         34722 $pl++;
3876 25732 100       45951 $pl ++ if $pad >= $len;
3877 25732         36072 $digit_after = '0';
3878 25732 50       55027 $digit_after = substr($xs, $pl, 1) if $pad > 0;
3879              
3880             # in case of 01234 we round down, for 6789 up, and only in case 5 we look
3881             # closer at the remaining digits of the original $x, remember decision
3882 25732         35887 my $round_up = 1; # default round up
3883             $round_up -- if
3884             ($mode eq 'trunc') || # trunc by round down
3885             ($digit_after =~ /[01234]/) || # round down anyway,
3886             # 6789 => round up
3887             ($digit_after eq '5') && # not 5000...0000
3888             ($x->_scan_for_nonzero($pad, $xs, $len) == 0) &&
3889             (
3890             ($mode eq 'even') && ($digit_round =~ /[24680]/) ||
3891             ($mode eq 'odd') && ($digit_round =~ /[13579]/) ||
3892             ($mode eq '+inf') && ($x->{sign} eq '-') ||
3893 25732 100 100     137554 ($mode eq '-inf') && ($x->{sign} eq '+') ||
      100        
      100        
      100        
      100        
3894             ($mode eq 'zero') # round down if zero, sign adjusted below
3895             );
3896 25732         41335 my $put_back = 0; # not yet modified
3897              
3898 25732 100 66     75953 if (($pad > 0) && ($pad <= $len)) {
    50          
3899 25610         57967 substr($xs, -$pad, $pad) = '0' x $pad; # replace with '00...'
3900 25610         46404 $xs =~ s/^0+(\d)/$1/; # "00000" -> "0"
3901 25610         37399 $put_back = 1; # need to put back
3902             } elsif ($pad > $len) {
3903 122         385 $x = $x->bzero(); # round to '0'
3904             }
3905              
3906 25732 100       50886 if ($round_up) { # what gave test above?
3907 12381         17197 $put_back = 1; # need to put back
3908 12381 100       23275 $pad = $len, $xs = '0' x $pad if $scale < 0; # tlr: whack 0.51=>1.0
3909              
3910             # we modify directly the string variant instead of creating a number and
3911             # adding it, since that is faster (we already have the string)
3912 12381         17567 my $c = 0;
3913 12381         16098 $pad ++; # for $pad == $len case
3914 12381         23012 while ($pad <= $len) {
3915 13696         26157 $c = substr($xs, -$pad, 1) + 1;
3916 13696 100       27077 $c = '0' if $c eq '10';
3917 13696         20751 substr($xs, -$pad, 1) = $c;
3918 13696         17780 $pad++;
3919 13696 100       28021 last if $c != 0; # no overflow => early out
3920             }
3921 12381 100       24934 $xs = '1'.$xs if $c == 0;
3922             }
3923 25732 100       89584 $x->{value} = $LIB->_new($xs) if $put_back == 1; # put back, if needed
3924              
3925 25732 100       68758 $x->{_a} = $scale if $scale >= 0;
3926 25732 100       50007 if ($scale < 0) {
3927 134         271 $x->{_a} = $len+$scale;
3928 134 100       302 $x->{_a} = 0 if $scale < -$len;
3929             }
3930 25732         73868 $x;
3931             }
3932              
3933             sub bfround {
3934             # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
3935             # $n == 0 || $n == 1 => round to integer
3936              
3937 212 50   212 1 765 my ($class, $x, @p) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3938              
3939 212         511 my ($scale, $mode) = $x->_scale_p(@p);
3940              
3941 212 50 33     1107 return $x if !defined $scale || $x->modify('bfround'); # no-op
3942              
3943             # no-op for Math::BigInt objects if $n <= 0
3944 212 100       583 $x = $x->bround($x->length()-$scale, $mode) if $scale > 0;
3945              
3946 212         401 $x->{_a} = undef;
3947 212         391 $x->{_p} = $scale; # store new _p
3948 212         556 $x;
3949             }
3950              
3951             sub fround {
3952             # Exists to make life easier for switch between MBF and MBI (should we
3953             # autoload fxxx() like MBF does for bxxx()?)
3954 0     0 0 0 my $x = shift;
3955 0 0       0 $x = __PACKAGE__->new($x) unless ref $x;
3956 0         0 $x->bround(@_);
3957             }
3958              
3959             sub bfloor {
3960             # round towards minus infinity; no-op since it's already integer
3961 36 50   36 1 450 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3962              
3963 36 50 66     130 return $upgrade -> bfloor($x)
3964             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3965              
3966 36         100 $x->round(@r);
3967             }
3968              
3969             sub bceil {
3970             # round towards plus infinity; no-op since it's already int
3971 36 50   36 1 445 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3972              
3973 36 50 66     137 return $upgrade -> bceil($x)
3974             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3975              
3976 36         89 $x->round(@r);
3977             }
3978              
3979             sub bint {
3980             # round towards zero; no-op since it's already integer
3981 38 50   38 1 393 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3982              
3983 38 50 66     148 return $upgrade -> bint($x)
3984             if defined($upgrade) && !$x -> isa(__PACKAGE__);
3985              
3986 38         103 $x->round(@r);
3987             }
3988              
3989             ###############################################################################
3990             # Other mathematical methods
3991             ###############################################################################
3992              
3993             sub bgcd {
3994             # (BINT or num_str, BINT or num_str) return BINT
3995             # does not modify arguments, but returns new object
3996             # GCD -- Euclid's algorithm, variant C (Knuth Vol 3, pg 341 ff)
3997              
3998             # Class::method(...) -> Class->method(...)
3999 97 100 100 97 1 2035 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
4000             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
4001             {
4002             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
4003             # " use is as a method instead";
4004 1         7 unshift @_, __PACKAGE__;
4005             }
4006              
4007 97         311 my ($class, @args) = objectify(0, @_);
4008              
4009             # Upgrade?
4010              
4011 97 100       270 if (defined $upgrade) {
4012 15         20 my $do_upgrade = 0;
4013 15         27 for my $arg (@args) {
4014 32 50       80 unless ($arg -> isa(__PACKAGE__)) {
4015 0         0 $do_upgrade = 1;
4016 0         0 last;
4017             }
4018             }
4019 15 50       34 return $upgrade -> bgcd(@args) if $do_upgrade;
4020             }
4021              
4022 97         162 my $x = shift @args;
4023 97 50 33     598 $x = defined(blessed($x)) && $x -> isa(__PACKAGE__) ? $x -> copy()
4024             : $class -> new($x);
4025              
4026 97 100       452 return $class->bnan() if $x->{sign} !~ /^[+-]$/; # x NaN?
4027              
4028 74         202 while (@args) {
4029 84         148 my $y = shift @args;
4030 84 50 33     439 $y = $class->new($y)
4031             unless defined(blessed($y)) && $y -> isa(__PACKAGE__);
4032 84 100       283 return $class->bnan() if $y->{sign} !~ /^[+-]$/; # y NaN?
4033 74         251 $x->{value} = $LIB->_gcd($x->{value}, $y->{value});
4034 74 100       217 last if $LIB->_is_one($x->{value});
4035             }
4036              
4037 64         174 return $x -> babs();
4038             }
4039              
4040             sub blcm {
4041             # (BINT or num_str, BINT or num_str) return BINT
4042             # does not modify arguments, but returns new object
4043             # Least Common Multiple
4044              
4045             # Class::method(...) -> Class->method(...)
4046 35 100 100 35 1 1302 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
4047             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
4048             {
4049             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
4050             # " use is as a method instead";
4051 1         7 unshift @_, __PACKAGE__;
4052             }
4053              
4054 35         116 my ($class, @args) = objectify(0, @_);
4055              
4056             # Upgrade?
4057              
4058 35 100       115 if (defined $upgrade) {
4059 8         13 my $do_upgrade = 0;
4060 8         13 for my $arg (@args) {
4061 16 50       75 unless ($arg -> isa(__PACKAGE__)) {
4062 0         0 $do_upgrade = 1;
4063 0         0 last;
4064             }
4065             }
4066 8 50       19 return $upgrade -> blcm(@args) if $do_upgrade;
4067             }
4068              
4069 35         63 my $x = shift @args;
4070 35 50 33     272 $x = defined(blessed($x)) && $x -> isa(__PACKAGE__) ? $x -> copy()
4071             : $class -> new($x);
4072 35 100       457 return $class->bnan() if $x->{sign} !~ /^[+-]$/; # x NaN?
4073              
4074 27         115 while (@args) {
4075 30         101 my $y = shift @args;
4076 30 50 33     192 $y = $class -> new($y)
4077             unless defined(blessed($y)) && $y -> isa(__PACKAGE__);
4078 30 100       126 return $x->bnan() if $y->{sign} !~ /^[+-]$/; # y not integer
4079 26         157 $x -> {value} = $LIB->_lcm($x -> {value}, $y -> {value});
4080             }
4081              
4082 23         78 return $x -> babs();
4083             }
4084              
4085             ###############################################################################
4086             # Object property methods
4087             ###############################################################################
4088              
4089             sub sign {
4090             # return the sign of the number: +/-/-inf/+inf/NaN
4091 8837 50   8837 1 25200 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4092              
4093 8837 50       17493 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4094              
4095 8837         29627 $x->{sign};
4096             }
4097              
4098             sub digit {
4099             # return the nth decimal digit, negative values count backward, 0 is right
4100 87 100   87 1 1013 my (undef, $x, $n, @r) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
4101              
4102 87 50       219 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4103              
4104 87 100       266 $n = $n->numify() if ref($n);
4105 87   100     382 $LIB->_digit($x->{value}, $n || 0);
4106             }
4107              
4108             sub bdigitsum {
4109             # like digitsum(), but assigns the result to the invocand
4110 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4111              
4112 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4113              
4114 0 0       0 return $x if $x -> is_nan();
4115 0 0       0 return $x -> bnan() if $x -> is_inf();
4116              
4117 0         0 $x -> {value} = $LIB -> _digitsum($x -> {value});
4118 0         0 $x -> {sign} = '+';
4119 0         0 return $x;
4120             }
4121              
4122             sub digitsum {
4123             # compute sum of decimal digits and return it
4124 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4125              
4126 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4127              
4128 0 0       0 return $class -> bnan() if $x -> is_nan();
4129 0 0       0 return $class -> bnan() if $x -> is_inf();
4130              
4131 0         0 my $y = $class -> bzero();
4132 0         0 $y -> {value} = $LIB -> _digitsum($x -> {value});
4133 0         0 $y -> round(@r);
4134             }
4135              
4136             sub length {
4137 26074 50   26074 1 68760 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4138              
4139 26074 50       53135 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4140              
4141 26074         64424 my $e = $LIB->_len($x->{value});
4142 26074 100       59087 wantarray ? ($e, 0) : $e;
4143             }
4144              
4145             sub exponent {
4146             # return a copy of the exponent (here always 0, NaN or 1 for $m == 0)
4147 72 50   72 1 523 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4148              
4149 72 50       162 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4150              
4151             # Upgrade?
4152              
4153 72 50 66     248 return $upgrade -> exponent($x, @r)
4154             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4155              
4156 72 100       239 if ($x->{sign} !~ /^[+-]$/) {
4157 24         40 my $s = $x->{sign};
4158 24         71 $s =~ s/^[+-]//; # NaN, -inf, +inf => NaN or inf
4159 24         66 return $class->new($s, @r);
4160             }
4161 48 100       131 return $class->bzero(@r) if $x->is_zero();
4162              
4163             # 12300 => 2 trailing zeros => exponent is 2
4164 40         135 $class->new($LIB->_zeros($x->{value}), @r);
4165             }
4166              
4167             sub mantissa {
4168             # return the mantissa (compatible to Math::BigFloat, e.g. reduced)
4169 68 50   68 1 469 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4170              
4171 68 50       159 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4172              
4173             # Upgrade?
4174              
4175 68 50 66     209 return $upgrade -> mantissa($x, @r)
4176             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4177              
4178 68 100       222 if ($x->{sign} !~ /^[+-]$/) {
4179             # for NaN, +inf, -inf: keep the sign
4180 24         71 return $class->new($x->{sign}, @r);
4181             }
4182 44         126 my $m = $x->copy();
4183 44         136 $m -> precision(undef);
4184 44         113 $m -> accuracy(undef);
4185              
4186             # that's a bit inefficient:
4187 44         153 my $zeros = $LIB->_zeros($m->{value});
4188 44 100       156 $m = $m->brsft($zeros, 10) if $zeros != 0;
4189 44         122 $m -> round(@r);
4190             }
4191              
4192             sub parts {
4193             # return a copy of both the exponent and the mantissa
4194 36 50   36 1 451 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4195              
4196 36 50       87 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4197              
4198             # Upgrade?
4199              
4200 36 50 66     124 return $upgrade -> parts($x, @r)
4201             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4202              
4203 36         89 ($x->mantissa(@r), $x->exponent(@r));
4204             }
4205              
4206             # Parts used for scientific notation with significand/mantissa and exponent as
4207             # integers. E.g., "12345.6789" is returned as "123456789" (mantissa) and "-4"
4208             # (exponent).
4209              
4210             sub sparts {
4211 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4212              
4213 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4214              
4215             # Not-a-number.
4216              
4217 0 0       0 if ($x -> is_nan()) {
4218 0         0 my $mant = $class -> bnan(@r); # mantissa
4219 0 0       0 return $mant unless wantarray; # scalar context
4220 0         0 my $expo = $class -> bnan(@r); # exponent
4221 0         0 return ($mant, $expo); # list context
4222             }
4223              
4224             # Infinity.
4225              
4226 0 0       0 if ($x -> is_inf()) {
4227 0         0 my $mant = $class -> binf($x->{sign}, @r); # mantissa
4228 0 0       0 return $mant unless wantarray; # scalar context
4229 0         0 my $expo = $class -> binf('+', @r); # exponent
4230 0         0 return ($mant, $expo); # list context
4231             }
4232              
4233             # Upgrade?
4234              
4235 0 0 0     0 return $upgrade -> sparts($x, @r)
4236             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4237              
4238             # Finite number.
4239              
4240 0         0 my $mant = $x -> copy();
4241 0         0 my $nzeros = $LIB -> _zeros($mant -> {value});
4242              
4243             $mant -> {value}
4244 0 0       0 = $LIB -> _rsft($mant -> {value}, $LIB -> _new($nzeros), 10)
4245             if $nzeros != 0;
4246 0 0       0 return $mant unless wantarray;
4247              
4248 0         0 my $expo = $class -> new($nzeros, @r);
4249 0         0 return ($mant, $expo);
4250             }
4251              
4252             # Parts used for normalized notation with significand/mantissa as either 0 or a
4253             # number in the semi-open interval [1,10). E.g., "12345.6789" is returned as
4254             # "1.23456789" and "4".
4255              
4256             sub nparts {
4257 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4258              
4259 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4260              
4261             # Not-a-Number and Infinity.
4262              
4263 0 0 0     0 return $x -> sparts(@r) if $x -> is_nan() || $x -> is_inf();
4264              
4265             # Upgrade?
4266              
4267 0 0 0     0 return $upgrade -> nparts($x, @r)
4268             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4269              
4270             # Finite number.
4271              
4272 0         0 my ($mant, $expo) = $x -> sparts(@r);
4273 0 0       0 if ($mant -> bcmp(0)) {
4274 0         0 my ($ndigtot, $ndigfrac) = $mant -> length();
4275 0         0 my $expo10adj = $ndigtot - $ndigfrac - 1;
4276              
4277 0 0       0 if ($expo10adj > 0) { # if mantissa is not an integer
4278 0 0       0 return $upgrade -> nparts($x, @r) if defined $upgrade;
4279 0         0 $mant = $mant -> bnan(@r);
4280 0 0       0 return $mant unless wantarray;
4281 0         0 $expo = $expo -> badd($expo10adj, @r);
4282 0         0 return ($mant, $expo);
4283             }
4284             }
4285              
4286 0 0       0 return $mant unless wantarray;
4287 0         0 return ($mant, $expo);
4288             }
4289              
4290             # Parts used for engineering notation with significand/mantissa as either 0 or a
4291             # number in the semi-open interval [1,1000) and the exponent is a multiple of 3.
4292             # E.g., "12345.6789" is returned as "12.3456789" and "3".
4293              
4294             sub eparts {
4295 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4296              
4297 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4298              
4299             # Not-a-number and Infinity.
4300              
4301 0 0 0     0 return $x -> sparts(@r) if $x -> is_nan() || $x -> is_inf();
4302              
4303             # Upgrade?
4304              
4305 0 0 0     0 return $upgrade -> eparts($x, @r)
4306             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4307              
4308             # Finite number.
4309              
4310 0         0 my ($mant, $expo) = $x -> sparts(@r);
4311              
4312 0 0       0 if ($mant -> bcmp(0)) {
4313 0         0 my $ndigmant = $mant -> length();
4314 0         0 $expo = $expo -> badd($ndigmant, @r);
4315              
4316             # $c is the number of digits that will be in the integer part of the
4317             # final mantissa.
4318              
4319 0         0 my $c = $expo -> copy() -> bdec() -> bmod(3) -> binc();
4320 0         0 $expo = $expo -> bsub($c);
4321              
4322 0 0       0 if ($ndigmant > $c) {
4323 0 0       0 return $upgrade -> eparts($x, @r) if defined $upgrade;
4324 0         0 $mant = $mant -> bnan(@r);
4325 0 0       0 return $mant unless wantarray;
4326 0         0 return ($mant, $expo);
4327             }
4328              
4329 0         0 $mant = $mant -> blsft($c - $ndigmant, 10, @r);
4330             }
4331              
4332 0 0       0 return $mant unless wantarray;
4333 0         0 return ($mant, $expo);
4334             }
4335              
4336             # Parts used for decimal notation, e.g., "12345.6789" is returned as "12345"
4337             # (integer part) and "0.6789" (fraction part).
4338              
4339             sub dparts {
4340 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4341              
4342 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4343              
4344             # Not-a-number.
4345              
4346 0 0       0 if ($x -> is_nan()) {
4347 0         0 my $int = $class -> bnan(@r);
4348 0 0       0 return $int unless wantarray;
4349 0         0 my $frc = $class -> bzero(@r); # or NaN?
4350 0         0 return ($int, $frc);
4351             }
4352              
4353             # Infinity.
4354              
4355 0 0       0 if ($x -> is_inf()) {
4356 0         0 my $int = $class -> binf($x->{sign}, @r);
4357 0 0       0 return $int unless wantarray;
4358 0         0 my $frc = $class -> bzero(@r);
4359 0         0 return ($int, $frc);
4360             }
4361              
4362             # Upgrade?
4363              
4364 0 0 0     0 return $upgrade -> dparts($x, @r)
4365             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4366              
4367             # Finite number.
4368              
4369 0         0 my $int = $x -> copy() -> round(@r);
4370 0 0       0 return $int unless wantarray;
4371              
4372 0         0 my $frc = $class -> bzero(@r);
4373 0         0 return ($int, $frc);
4374             }
4375              
4376             # Fractional parts with the numerator and denominator as integers. E.g.,
4377             # "123.4375" is returned as "1975" and "16".
4378              
4379             sub fparts {
4380 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4381              
4382 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4383              
4384             # NaN => NaN/NaN
4385              
4386 0 0       0 if ($x -> is_nan()) {
4387 0 0       0 return $class -> bnan(@r) unless wantarray;
4388 0         0 return $class -> bnan(@r), $class -> bnan(@r);
4389             }
4390              
4391             # ±Inf => ±Inf/1
4392              
4393 0 0       0 if ($x -> is_inf()) {
4394 0         0 my $numer = $class -> binf($x->{sign}, @r);
4395 0 0       0 return $numer unless wantarray;
4396 0         0 my $denom = $class -> bone(@r);
4397 0         0 return $numer, $denom;
4398             }
4399              
4400             # Upgrade?
4401              
4402 0 0 0     0 return $upgrade -> fparts($x, @r)
4403             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4404              
4405             # N => N/1
4406              
4407 0         0 my $numer = $x -> copy() -> round(@r);
4408 0 0       0 return $numer unless wantarray;
4409 0         0 my $denom = $class -> bone(@r);
4410 0         0 return $numer, $denom;
4411             }
4412              
4413             sub numerator {
4414 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4415              
4416 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4417              
4418 0 0 0     0 return $upgrade -> numerator($x, @r)
4419             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4420              
4421 0         0 return $x -> copy() -> round(@r);
4422             }
4423              
4424             sub denominator {
4425 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4426              
4427 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4428              
4429 0 0 0     0 return $upgrade -> denominator($x, @r)
4430             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4431              
4432 0 0       0 return $x -> is_nan() ? $class -> bnan(@r) : $class -> bone(@r);
4433             }
4434              
4435             ###############################################################################
4436             # String conversion methods
4437             ###############################################################################
4438              
4439             sub bstr {
4440 12036 100   12036 1 1931845 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4441              
4442 12036 50       32395 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4443              
4444             # Inf and NaN
4445              
4446 12036 100 100     42669 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4447 2703 100       25316 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4448 544         5013 return 'inf'; # +inf
4449             }
4450              
4451             # Upgrade?
4452              
4453 9333 50 66     24406 return $upgrade -> bstr($x, @r)
4454             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4455              
4456             # Finite number
4457              
4458 9333         32931 my $str = $LIB->_str($x->{value});
4459 9333 100       114940 return $x->{sign} eq '-' ? "-$str" : $str;
4460             }
4461              
4462             # Scientific notation with significand/mantissa as an integer, e.g., "12345" is
4463             # written as "1.2345e+4".
4464              
4465             sub bsstr {
4466 66 100   66 1 10234 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4467              
4468 66 50       165 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4469              
4470             # Inf and NaN
4471              
4472 66 100 100     274 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4473 18 100       146 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4474 7         66 return 'inf'; # +inf
4475             }
4476              
4477             # Upgrade?
4478              
4479 48 50 66     148 return $upgrade -> bsstr($x, @r)
4480             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4481              
4482             # Finite number
4483              
4484 48         161 my $expo = $LIB -> _zeros($x->{value});
4485 48         1293 my $mant = $LIB -> _str($x->{value});
4486 48 100       145 $mant = substr($mant, 0, -$expo) if $expo; # strip trailing zeros
4487              
4488 48 100       534 ($x->{sign} eq '-' ? '-' : '') . $mant . 'e+' . $expo;
4489             }
4490              
4491             # Normalized notation, e.g., "12345" is written as "1.2345e+4".
4492              
4493             sub bnstr {
4494 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4495              
4496 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4497              
4498             # Inf and NaN
4499              
4500 0 0 0     0 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4501 0 0       0 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4502 0         0 return 'inf'; # +inf
4503             }
4504              
4505             # Upgrade?
4506              
4507 0 0 0     0 return $upgrade -> bnstr($x, @r)
4508             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4509              
4510             # Finite number
4511              
4512 0         0 my $expo = $LIB -> _zeros($x->{value});
4513 0         0 my $mant = $LIB -> _str($x->{value});
4514 0 0       0 $mant = substr($mant, 0, -$expo) if $expo; # strip trailing zeros
4515              
4516 0         0 my $mantlen = CORE::length($mant);
4517 0 0       0 if ($mantlen > 1) {
4518 0         0 $expo += $mantlen - 1; # adjust exponent
4519 0         0 substr $mant, 1, 0, "."; # insert decimal point
4520             }
4521              
4522 0 0       0 ($x->{sign} eq '-' ? '-' : '') . $mant . 'e+' . $expo;
4523             }
4524              
4525             # Engineering notation, e.g., "12345" is written as "12.345e+3".
4526              
4527             sub bestr {
4528 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4529              
4530 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4531              
4532             # Inf and NaN
4533              
4534 0 0 0     0 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4535 0 0       0 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4536 0         0 return 'inf'; # +inf
4537             }
4538              
4539             # Upgrade?
4540              
4541 0 0 0     0 return $upgrade -> bestr($x, @r)
4542             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4543              
4544             # Finite number
4545              
4546 0         0 my $expo = $LIB -> _zeros($x->{value}); # number of trailing zeros
4547 0         0 my $mant = $LIB -> _str($x->{value}); # mantissa as a string
4548 0 0       0 $mant = substr($mant, 0, -$expo) if $expo; # strip trailing zeros
4549 0         0 my $mantlen = CORE::length($mant); # length of mantissa
4550 0         0 $expo += $mantlen;
4551              
4552 0         0 my $dotpos = ($expo - 1) % 3 + 1; # offset of decimal point
4553 0         0 $expo -= $dotpos;
4554              
4555 0 0       0 if ($dotpos < $mantlen) {
    0          
4556 0         0 substr $mant, $dotpos, 0, "."; # insert decimal point
4557             } elsif ($dotpos > $mantlen) {
4558 0         0 $mant .= "0" x ($dotpos - $mantlen); # append zeros
4559             }
4560              
4561 0 0       0 ($x->{sign} eq '-' ? '-' : '') . $mant . 'e+' . $expo;
4562             }
4563              
4564             # Decimal notation, e.g., "12345" (no exponent).
4565              
4566             sub bdstr {
4567 24 50   24 1 82 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4568              
4569 24 50       56 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4570              
4571             # Inf and NaN
4572              
4573 24 100 100     86 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4574 8 100       33 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4575 1         4 return 'inf'; # +inf
4576             }
4577              
4578             # Upgrade?
4579              
4580 16 50 33     97 return $upgrade -> bdstr($x, @r)
4581             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4582              
4583             # Finite number
4584              
4585 16 100       67 ($x->{sign} eq '-' ? '-' : '') . $LIB->_str($x->{value});
4586             }
4587              
4588             # Fraction notation, e.g., "123.4375" is written as "1975/16", but "123" is
4589             # written as "123", not "123/1".
4590              
4591             sub bfstr {
4592 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4593              
4594 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4595              
4596             # Inf and NaN
4597              
4598 0 0 0     0 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4599 0 0       0 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4600 0         0 return 'inf'; # +inf
4601             }
4602              
4603             # Upgrade?
4604              
4605 0 0 0     0 return $upgrade -> bfstr($x, @r)
4606             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4607              
4608             # Finite number
4609              
4610 0 0       0 ($x->{sign} eq '-' ? '-' : '') . $LIB->_str($x->{value});
4611             }
4612              
4613             sub to_hex {
4614             # return as hex string with no prefix
4615              
4616 36 50   36 1 532 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4617              
4618 36 50       101 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4619              
4620             # Inf and NaN
4621              
4622 36 100 100     166 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4623 12 100       107 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4624 4         48 return 'inf'; # +inf
4625             }
4626              
4627             # Upgrade?
4628              
4629 24 50 66     90 return $upgrade -> to_hex($x, @r)
4630             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4631              
4632             # Finite number
4633              
4634 24         131 my $hex = $LIB->_to_hex($x->{value});
4635 24 100       293 return $x->{sign} eq '-' ? "-$hex" : $hex;
4636             }
4637              
4638             sub to_oct {
4639             # return as octal string with no prefix
4640              
4641 40 50   40 1 541 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4642              
4643 40 50       105 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4644              
4645             # Inf and NaN
4646              
4647 40 100 100     151 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4648 12 100       121 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4649 4         43 return 'inf'; # +inf
4650             }
4651              
4652             # Upgrade?
4653              
4654 28 50 66     102 return $upgrade -> to_oct($x, @r)
4655             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4656              
4657             # Finite number
4658              
4659 28         116 my $oct = $LIB->_to_oct($x->{value});
4660 28 100       339 return $x->{sign} eq '-' ? "-$oct" : $oct;
4661             }
4662              
4663             sub to_bin {
4664             # return as binary string with no prefix
4665              
4666 93 50   93 1 689 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4667              
4668 93 50       289 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4669              
4670             # Inf and NaN
4671              
4672 93 100 100     397 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
4673 12 100       174 return $x->{sign} unless $x->{sign} eq '+inf'; # -inf, NaN
4674 4         44 return 'inf'; # +inf
4675             }
4676              
4677             # Upgrade?
4678              
4679 81 50 66     203 return $upgrade -> to_bin($x, @r)
4680             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4681              
4682             # Finite number
4683              
4684 81         329 my $bin = $LIB->_to_bin($x->{value});
4685 81 100       476 return $x->{sign} eq '-' ? "-$bin" : $bin;
4686             }
4687              
4688             sub to_bytes {
4689             # return a byte string
4690              
4691 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4692              
4693 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4694              
4695 0 0 0     0 croak("to_bytes() requires a finite, non-negative integer")
4696             if $x -> is_neg() || ! $x -> is_int();
4697              
4698 0 0 0     0 return $upgrade -> to_bytes($x, @r)
4699             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4700              
4701 0 0       0 croak("to_bytes() requires a newer version of the $LIB library.")
4702             unless $LIB->can('_to_bytes');
4703              
4704 0         0 return $LIB->_to_bytes($x->{value});
4705             }
4706              
4707             sub to_base {
4708             # return a base anything string
4709              
4710             # $cs is the collation sequence
4711 0 0 0 0 1 0 my ($class, $x, $base, $cs, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
4712             ? (ref($_[0]), @_) : objectify(2, @_);
4713              
4714 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4715              
4716 0 0 0     0 croak("the value to convert must be a finite, non-negative integer")
4717             if $x -> is_neg() || !$x -> is_int();
4718              
4719 0 0 0     0 croak("the base must be a finite integer >= 2")
4720             if $base < 2 || ! $base -> is_int();
4721              
4722             # If no collating sequence is given, pass some of the conversions to
4723             # methods optimized for those cases.
4724              
4725 0 0       0 unless (defined $cs) {
4726 0 0       0 return $x -> to_bin() if $base == 2;
4727 0 0       0 return $x -> to_oct() if $base == 8;
4728 0 0       0 return uc $x -> to_hex() if $base == 16;
4729 0 0       0 return $x -> bstr() if $base == 10;
4730             }
4731              
4732 0 0       0 croak("to_base() requires a newer version of the $LIB library.")
4733             unless $LIB->can('_to_base');
4734              
4735 0 0 0     0 return $upgrade -> to_base($x, $base, $cs, @r)
      0        
4736             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
4737             !$base -> isa(__PACKAGE__));
4738              
4739             return $LIB->_to_base($x->{value}, $base -> {value},
4740 0 0       0 defined($cs) ? $cs : ());
4741             }
4742              
4743             sub to_base_num {
4744             # return a base anything array ref, e.g.,
4745             # Math::BigInt -> new(255) -> to_base_num(10) returns [2, 5, 5];
4746              
4747             # $cs is the collation sequence
4748 0 0 0 0 1 0 my ($class, $x, $base, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
4749             ? (ref($_[0]), @_) : objectify(2, @_);
4750              
4751 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4752              
4753 0 0 0     0 croak("the value to convert must be a finite non-negative integer")
4754             if $x -> is_neg() || !$x -> is_int();
4755              
4756 0 0 0     0 croak("the base must be a finite integer >= 2")
4757             if $base < 2 || ! $base -> is_int();
4758              
4759 0 0       0 croak("to_base() requires a newer version of the $LIB library.")
4760             unless $LIB->can('_to_base');
4761              
4762 0 0 0     0 return $upgrade -> to_base_num($x, $base, @r)
      0        
4763             if defined($upgrade) && (!$x -> isa(__PACKAGE__) ||
4764             !$base -> isa(__PACKAGE__));
4765              
4766             # Get a reference to an array of library thingies, and replace each element
4767             # with a Math::BigInt object using that thingy.
4768              
4769 0         0 my $vals = $LIB -> _to_base_num($x->{value}, $base -> {value});
4770              
4771 0         0 for my $i (0 .. $#$vals) {
4772 0         0 my $x = $class -> bzero();
4773 0         0 $x -> {value} = $vals -> [$i];
4774 0         0 $vals -> [$i] = $x;
4775             }
4776              
4777 0         0 return $vals;
4778             }
4779              
4780             sub as_hex {
4781             # return as hex string, with prefixed 0x
4782              
4783 36 50   36 1 470 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4784              
4785 36 50       121 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4786              
4787 36 100       166 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4788              
4789 24 50 66     88 return $upgrade -> as_hex($x, @r)
4790             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4791              
4792 24         100 my $hex = $LIB->_as_hex($x->{value});
4793 24 100       254 return $x->{sign} eq '-' ? "-$hex" : $hex;
4794             }
4795              
4796             sub as_oct {
4797             # return as octal string, with prefixed 0
4798              
4799 40 50   40 1 526 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4800              
4801 40 50       103 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4802              
4803 40 100       174 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4804              
4805 28 50 66     97 return $upgrade -> as_oct($x, @r)
4806             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4807              
4808 28         110 my $oct = $LIB->_as_oct($x->{value});
4809 28 100       301 return $x->{sign} eq '-' ? "-$oct" : $oct;
4810             }
4811              
4812             sub as_bin {
4813             # return as binary string, with prefixed 0b
4814              
4815 39 50   39 1 523 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4816              
4817 39 50       103 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4818              
4819 39 100       166 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, nan etc
4820              
4821 27 50 66     97 return $upgrade -> as_bin($x, @r)
4822             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4823              
4824 27         103 my $bin = $LIB->_as_bin($x->{value});
4825 27 100       284 return $x->{sign} eq '-' ? "-$bin" : $bin;
4826             }
4827              
4828             *as_bytes = \&to_bytes;
4829              
4830             ###############################################################################
4831             # Other conversion methods
4832             ###############################################################################
4833              
4834             sub numify {
4835             # Make a Perl scalar number from a Math::BigInt object.
4836 495 50   495 1 1696 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4837              
4838 495 50       1065 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
4839              
4840 495 50       1244 if ($x -> is_nan()) {
4841 0         0 require Math::Complex;
4842 0         0 my $inf = $Math::Complex::Inf;
4843 0         0 return $inf - $inf;
4844             }
4845              
4846 495 50       1097 if ($x -> is_inf()) {
4847 0         0 require Math::Complex;
4848 0         0 my $inf = $Math::Complex::Inf;
4849 0 0       0 return $x -> is_negative() ? -$inf : $inf;
4850             }
4851              
4852 495 50 66     1329 return $upgrade -> numify($x, @r)
4853             if defined($upgrade) && !$x -> isa(__PACKAGE__);
4854              
4855 495         1662 my $num = 0 + $LIB->_num($x->{value});
4856 495 100       1835 return $x->{sign} eq '-' ? -$num : $num;
4857             }
4858              
4859             ###############################################################################
4860             # Private methods and functions.
4861             ###############################################################################
4862              
4863             sub objectify {
4864             # Convert strings and "foreign objects" to the objects we want.
4865              
4866             # The first argument, $count, is the number of following arguments that
4867             # objectify() looks at and converts to objects. The first is a classname.
4868             # If the given count is 0, all arguments will be used.
4869              
4870             # After the count is read, objectify obtains the name of the class to which
4871             # the following arguments are converted. If the second argument is a
4872             # reference, use the reference type as the class name. Otherwise, if it is
4873             # a string that looks like a class name, use that. Otherwise, use $class.
4874              
4875             # Caller: Gives us:
4876             #
4877             # $x->badd(1); => ref x, scalar y
4878             # Class->badd(1, 2); => classname x (scalar), scalar x, scalar y
4879             # Class->badd(Class->(1), 2); => classname x (scalar), ref x, scalar y
4880             # Math::BigInt::badd(1, 2); => scalar x, scalar y
4881              
4882             # A shortcut for the common case $x->unary_op(), in which case the argument
4883             # list is (0, $x) or (1, $x).
4884              
4885 5151 100 100 5151   30556 return (ref($_[1]), $_[1]) if @_ == 2 && ($_[0] || 0) == 1 && ref($_[1]);
      100        
      66        
4886              
4887             # Check the context.
4888              
4889 5001 50       11024 unless (wantarray) {
4890 0         0 croak(__PACKAGE__ . "::objectify() needs list context");
4891             }
4892              
4893             # Get the number of arguments to objectify.
4894              
4895 5001         8554 my $count = shift;
4896              
4897             # Initialize the output array.
4898              
4899 5001         11250 my @a = @_;
4900              
4901             # If the first argument is a reference, use that reference type as our
4902             # class name. Otherwise, if the first argument looks like a class name,
4903             # then use that as our class name. Otherwise, use the default class name.
4904              
4905 5001         7129 my $class;
4906 5001 100       13507 if (ref($a[0])) { # reference?
    100          
4907 3728         6363 $class = ref($a[0]);
4908             } elsif ($a[0] =~ /^[A-Z].*::/) { # string with class name?
4909 1261         2606 $class = shift @a;
4910             } else {
4911 12         31 $class = __PACKAGE__; # default class name
4912             }
4913              
4914 5001   66     11250 $count ||= @a;
4915 5001         12613 unshift @a, $class;
4916              
4917 51     51   518 no strict 'refs';
  51         140  
  51         80992  
4918              
4919             # What we upgrade to, if anything. Note that we need the whole upgrade
4920             # chain, since there might be multiple levels of upgrading. E.g., class A
4921             # upgrades to class B, which upgrades to class C. Delay getting the chain
4922             # until we actually need it.
4923              
4924 5001         8167 my @upg = ();
4925 5001         7277 my $have_upgrade_chain = 0;
4926              
4927             # Disable downgrading, because Math::BigFloat -> foo('1.0', '2.0') needs
4928             # floats.
4929              
4930 5001         6838 my $down;
4931 5001 100       6849 if (defined ${"$a[0]::downgrade"}) {
  5001         18923  
4932 14         25 $down = ${"$a[0]::downgrade"};
  14         37  
4933 14         21 ${"$a[0]::downgrade"} = undef;
  14         30  
4934             }
4935              
4936 5001         12761 ARG: for my $i (1 .. $count) {
4937              
4938 9136         17687 my $ref = ref $a[$i];
4939              
4940             # Perl scalars are fed to the appropriate constructor.
4941              
4942 9136 100       17574 unless ($ref) {
4943 4214         11645 $a[$i] = $a[0] -> new($a[$i]);
4944 4214         15427 next;
4945             }
4946              
4947             # If it is an object of the right class, all is fine.
4948              
4949 4922 100       16770 next if $ref -> isa($a[0]);
4950              
4951             # Upgrading is OK, so skip further tests if the argument is upgraded,
4952             # but first get the whole upgrade chain if we haven't got it yet.
4953              
4954 404 100       960 unless ($have_upgrade_chain) {
4955 281         476 my $cls = $class;
4956 281         800 my $upg = $cls -> upgrade();
4957 281         818 while (defined $upg) {
4958 17 50       43 last if $upg eq $cls;
4959 17         50 push @upg, $upg;
4960 17         36 $cls = $upg;
4961 17         62 $upg = $cls -> upgrade();
4962             }
4963 281         508 $have_upgrade_chain = 1;
4964             }
4965              
4966 404         765 for my $upg (@upg) {
4967 17 100       53 next ARG if $ref -> isa($upg);
4968             }
4969              
4970             # See if we can call one of the as_xxx() methods. We don't know whether
4971             # the as_xxx() method returns an object or a scalar, so re-check
4972             # afterwards.
4973              
4974 388         608 my $recheck = 0;
4975              
4976 388 100       1208 if ($a[0] -> isa('Math::BigInt')) {
    50          
4977 42 50       188 if ($a[$i] -> can('as_int')) {
    0          
4978 42         140 $a[$i] = $a[$i] -> as_int();
4979 42         117 $recheck = 1;
4980             } elsif ($a[$i] -> can('as_number')) {
4981 0         0 $a[$i] = $a[$i] -> as_number();
4982 0         0 $recheck = 1;
4983             }
4984             }
4985              
4986             elsif ($a[0] -> isa('Math::BigFloat')) {
4987 346 50       1427 if ($a[$i] -> can('as_float')) {
4988 346         794 $a[$i] = $a[$i] -> as_float();
4989 346         846 $recheck = $1;
4990             }
4991             }
4992              
4993             # If we called one of the as_xxx() methods, recheck.
4994              
4995 388 100       1013 if ($recheck) {
4996 44         111 $ref = ref($a[$i]);
4997              
4998             # Perl scalars are fed to the appropriate constructor.
4999              
5000 44 50       109 unless ($ref) {
5001 0         0 $a[$i] = $a[0] -> new($a[$i]);
5002 0         0 next;
5003             }
5004              
5005             # If it is an object of the right class, all is fine.
5006              
5007 44 100       216 next if $ref -> isa($a[0]);
5008             }
5009              
5010             # Last resort.
5011              
5012 345         967 $a[$i] = $a[0] -> new($a[$i]);
5013             }
5014              
5015             # Reset the downgrading.
5016              
5017 5001         7799 ${"$a[0]::downgrade"} = $down;
  5001         13416  
5018              
5019 5001         18658 return @a;
5020             }
5021              
5022             sub import {
5023 103     103   4140 my $class = shift;
5024 103         223 $IMPORT++; # remember we did import()
5025 103         213 my @a; # unrecognized arguments
5026              
5027 103         376 while (@_) {
5028 91         209 my $param = shift;
5029              
5030             # Enable overloading of constants.
5031              
5032 91 100       337 if ($param eq ':constant') {
5033             overload::constant
5034              
5035             integer => sub {
5036 2     2   10 $class -> new(shift);
5037             },
5038              
5039             float => sub {
5040 0     0   0 $class -> new(shift);
5041             },
5042              
5043             binary => sub {
5044             # E.g., a literal 0377 shall result in an object whose value
5045             # is decimal 255, but new("0377") returns decimal 377.
5046 0 0   0   0 return $class -> from_oct($_[0]) if $_[0] =~ /^0_*[0-7]/;
5047 0         0 $class -> new(shift);
5048 1         9 };
5049 1         45 next;
5050             }
5051              
5052             # Upgrading.
5053              
5054 90 100       322 if ($param eq 'upgrade') {
5055 2         9 $class -> upgrade(shift);
5056 2         9 next;
5057             }
5058              
5059             # Downgrading.
5060              
5061 88 50       324 if ($param eq 'downgrade') {
5062 0         0 $class -> downgrade(shift);
5063 0         0 next;
5064             }
5065              
5066             # Accuracy.
5067              
5068 88 50       280 if ($param eq 'accuracy') {
5069 0         0 $class -> accuracy(shift);
5070 0         0 next;
5071             }
5072              
5073             # Precision.
5074              
5075 88 50       333 if ($param eq 'precision') {
5076 0         0 $class -> precision(shift);
5077 0         0 next;
5078             }
5079              
5080             # Rounding mode.
5081              
5082 88 50       264 if ($param eq 'round_mode') {
5083 0         0 $class -> round_mode(shift);
5084 0         0 next;
5085             }
5086              
5087             # Backend library.
5088              
5089 88 100       610 if ($param =~ /^(lib|try|only)\z/) {
5090             # try => 0 (no warn if unavailable module)
5091             # lib => 1 (warn on fallback)
5092             # only => 2 (die on fallback)
5093              
5094             # Get the list of user-specified libraries.
5095              
5096 29 50       128 croak "Library argument for import parameter '$param' is missing"
5097             unless @_;
5098 29         60 my $libs = shift;
5099 29 50       109 croak "Library argument for import parameter '$param' is undefined"
5100             unless defined($libs);
5101              
5102             # Check and clean up the list of user-specified libraries.
5103              
5104 29         57 my @libs;
5105 29         170 for my $lib (split /,/, $libs) {
5106 29         117 $lib =~ s/^\s+//;
5107 29         98 $lib =~ s/\s+$//;
5108              
5109 29 50       146 if ($lib =~ /[^a-zA-Z0-9_:]/) {
5110 0         0 carp "Library name '$lib' contains invalid characters";
5111 0         0 next;
5112             }
5113              
5114 29 50       112 if (! CORE::length $lib) {
5115 0         0 carp "Library name is empty";
5116 0         0 next;
5117             }
5118              
5119 29 100       140 $lib = "Math::BigInt::$lib" if $lib !~ /^Math::BigInt::/i;
5120              
5121             # If a library has already been loaded, that is OK only if the
5122             # requested library is identical to the loaded one.
5123              
5124 29 100       111 if (defined($LIB)) {
5125 10 100       43 if ($lib ne $LIB) {
5126             #carp "Library '$LIB' has already been loaded, so",
5127             # " ignoring requested library '$lib'";
5128             }
5129 10         47 next;
5130             }
5131              
5132 19         76 push @libs, $lib;
5133             }
5134              
5135 29 100       144 next if defined $LIB;
5136              
5137 19 50       59 croak "Library list contains no valid libraries" unless @libs;
5138              
5139             # Try to load the specified libraries, if any.
5140              
5141 19         94 for (my $i = 0 ; $i <= $#libs ; $i++) {
5142 19         44 my $lib = $libs[$i];
5143 19         1525 eval "require $lib";
5144 19 50       4488 unless ($@) {
5145 19         56 $LIB = $lib;
5146 19         57 last;
5147             }
5148             }
5149              
5150 19 50       145 next if defined $LIB;
5151              
5152             # No library has been loaded, and none of the requested libraries
5153             # could be loaded, and fallback and the user doesn't allow fallback.
5154              
5155 0 0       0 if ($param eq 'only') {
5156 0         0 croak "Couldn't load the specified math lib(s) ",
5157             join(", ", map "'$_'", @libs),
5158             ", and fallback to '$DEFAULT_LIB' is not allowed";
5159             }
5160              
5161             # No library has been loaded, and none of the requested libraries
5162             # could be loaded, but the user accepts the use of a fallback
5163             # library, so try to load it.
5164              
5165 0         0 eval "require $DEFAULT_LIB";
5166 0 0       0 if ($@) {
5167 0         0 croak "Couldn't load the specified math lib(s) ",
5168             join(", ", map "'$_'", @libs),
5169             ", not even the fallback lib '$DEFAULT_LIB'";
5170             }
5171              
5172             # The fallback library was successfully loaded, but the user
5173             # might want to know that we are using the fallback.
5174              
5175 0 0       0 if ($param eq 'lib') {
5176 0         0 carp "Couldn't load the specified math lib(s) ",
5177             join(", ", map "'$_'", @libs),
5178             ", so using fallback lib '$DEFAULT_LIB'";
5179             }
5180              
5181 0         0 next;
5182             }
5183              
5184             # Unrecognized parameter.
5185              
5186 59         253 push @a, $param;
5187             }
5188              
5189             # Any non-':constant' stuff is handled by our parent, Exporter
5190              
5191 103 100       345 if (@a) {
5192 58         2921 $class->SUPER::import(@a); # need it for subclasses
5193 58         5458 $class->export_to_level(1, $class, @a); # need it for Math::BigFloat
5194             }
5195              
5196             # We might not have loaded any backend library yet, either because the user
5197             # didn't specify any, or because the specified libraries failed to load and
5198             # the user allows the use of a fallback library.
5199              
5200 103 100       16999 unless (defined $LIB) {
5201 32         2526 eval "require $DEFAULT_LIB";
5202 32 50       272 if ($@) {
5203 0         0 croak "No lib specified, and couldn't load the default",
5204             " lib '$DEFAULT_LIB'";
5205             }
5206 32         2409 $LIB = $DEFAULT_LIB;
5207             }
5208              
5209             # import done
5210             }
5211              
5212             sub _trailing_zeros {
5213             # return the amount of trailing zeros in $x (as scalar)
5214 0     0   0 my $x = shift;
5215 0 0       0 $x = __PACKAGE__->new($x) unless ref $x;
5216              
5217 0 0       0 return 0 if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf etc
5218              
5219 0         0 $LIB->_zeros($x->{value}); # must handle odd values, 0 etc
5220             }
5221              
5222             sub _scan_for_nonzero {
5223             # internal, used by bround() to scan for non-zeros after a '5'
5224 2983     2983   7524 my ($x, $pad, $xs, $len) = @_;
5225              
5226 2983 100       6304 return 0 if $len == 1; # "5" is trailed by invisible zeros
5227 2960         4435 my $follow = $pad - 1;
5228 2960 100 66     22559 return 0 if $follow > $len || $follow < 1;
5229              
5230             # use the string form to check whether only '0's follow or not
5231 2307 100       13755 substr ($xs, -$follow) =~ /[^0]/ ? 1 : 0;
5232             }
5233              
5234             sub _find_round_parameters {
5235             # After any operation or when calling round(), the result is rounded by
5236             # regarding the A & P from arguments, local parameters, or globals.
5237              
5238             # !!!!!!! If you change this, remember to change round(), too! !!!!!!!!!!
5239              
5240             # This procedure finds the round parameters, but it is for speed reasons
5241             # duplicated in round. Otherwise, it is tested by the testsuite and used
5242             # by bdiv().
5243              
5244             # returns ($self) or ($self, $a, $p, $r) - sets $self to NaN of both A and P
5245             # were requested/defined (locally or globally or both)
5246              
5247 10202     10202   55901 my ($self, $a, $p, $r, @args) = @_;
5248             # $a accuracy, if given by caller
5249             # $p precision, if given by caller
5250             # $r round_mode, if given by caller
5251             # @args all 'other' arguments (0 for unary, 1 for binary ops)
5252              
5253 10202         19935 my $class = ref($self); # find out class of argument(s)
5254 51     51   537 no strict 'refs';
  51         201  
  51         21898  
5255              
5256             # convert to normal scalar for speed and correctness in inner parts
5257 10202 50 100     34362 $a = $a->can('numify') ? $a->numify() : "$a" if defined $a && ref($a);
    100          
5258 10202 0 66     22842 $p = $p->can('numify') ? $p->numify() : "$p" if defined $p && ref($p);
    50          
5259              
5260             # now pick $a or $p, but only if we have got "arguments"
5261 10202 100       20580 if (!defined $a) {
5262 994         2339 foreach ($self, @args) {
5263             # take the defined one, or if both defined, the one that is smaller
5264             $a = $_->{_a}
5265 1568 50 33     4205 if (defined $_->{_a}) && (!defined $a || $_->{_a} < $a);
      66        
5266             }
5267             }
5268 10202 100       19128 if (!defined $p) {
5269             # even if $a is defined, take $p, to signal error for both defined
5270 10150         19087 foreach ($self, @args) {
5271             # take the defined one, or if both defined, the one that is bigger
5272             # -2 > -3, and 3 > 2
5273             $p = $_->{_p}
5274 18981 50 33     40982 if (defined $_->{_p}) && (!defined $p || $_->{_p} > $p);
      66        
5275             }
5276             }
5277              
5278             # if still none defined, use globals (#2)
5279 10202 100       18554 $a = ${"$class\::accuracy"} unless defined $a;
  962         3083  
5280 10202 100       18926 $p = ${"$class\::precision"} unless defined $p;
  10140         29045  
5281              
5282             # A == 0 is useless, so undef it to signal no rounding
5283 10202 100 100     33214 $a = undef if defined $a && $a == 0;
5284              
5285             # no rounding today?
5286 10202 100 100     25513 return ($self) unless defined $a || defined $p; # early out
5287              
5288             # set A and set P is an fatal error
5289 9291 100 100     27118 return ($self->bnan()) if defined $a && defined $p; # error
5290              
5291 9282 100       15921 $r = ${"$class\::round_mode"} unless defined $r;
  9273         21271  
5292 9282 100       38945 if ($r !~ /^(even|odd|[+-]inf|zero|trunc|common)$/) {
5293 3         486 croak("Unknown round mode '$r'");
5294             }
5295              
5296 9279 100       20137 $a = int($a) if defined $a;
5297 9279 100       16795 $p = int($p) if defined $p;
5298              
5299 9279         39229 ($self, $a, $p, $r);
5300             }
5301              
5302             # Return true if the input is numeric and false if it is a string.
5303              
5304             sub _is_numeric {
5305 0     0   0 shift; # class name
5306 0         0 my $value = shift;
5307 51     51   460 no warnings 'numeric';
  51         136  
  51         147710  
5308             # detect numbers
5309             # string & "" -> ""
5310             # number & "" -> 0 (with warning)
5311             # nan and inf can detect as numbers, so check with * 0
5312 0 0       0 return unless CORE::length((my $dummy = "") & $value);
5313 0 0       0 return unless 0 + $value eq $value;
5314 0 0       0 return 1 if $value * 0 == 0;
5315 0         0 return -1; # Inf/NaN
5316             }
5317              
5318             # Trims the sign of the significand, the (absolute value of the) significand,
5319             # the sign of the exponent, and the (absolute value of the) exponent. The
5320             # returned values have no underscores ("_") or unnecessary leading or trailing
5321             # zeros.
5322              
5323             sub _trim_split_parts {
5324 10064     10064   14773 shift; # class name
5325              
5326 10064   100     37281 my $sig_sgn = shift() || '+';
5327 10064   100     30061 my $sig_str = shift() || '0';
5328 10064   100     29431 my $exp_sgn = shift() || '+';
5329 10064   100     28532 my $exp_str = shift() || '0';
5330              
5331 10064         20591 $sig_str =~ tr/_//d; # "1.0_0_0" -> "1.000"
5332 10064         30920 $sig_str =~ s/^0+//; # "01.000" -> "1.000"
5333 10064 100       29187 $sig_str =~ s/\.0*$// # "1.000" -> "1"
5334             || $sig_str =~ s/(\..*[^0])0+$/$1/; # "1.010" -> "1.01"
5335 10064 100       22258 $sig_str = '0' unless CORE::length($sig_str);
5336              
5337 10064 100       35087 return '+', '0', '+', '0' if $sig_str eq '0';
5338              
5339 5308         8297 $exp_str =~ tr/_//d; # "01_234" -> "01234"
5340 5308         17476 $exp_str =~ s/^0+//; # "01234" -> "1234"
5341 5308 100       13828 $exp_str = '0' unless CORE::length($exp_str);
5342 5308 100       12626 $exp_sgn = '+' if $exp_str eq '0'; # "+3e-0" -> "+3e+0"
5343              
5344 5308         25517 return $sig_sgn, $sig_str, $exp_sgn, $exp_str;
5345             }
5346              
5347             # Takes any string representing a valid decimal number and splits it into four
5348             # strings: the sign of the significand, the absolute value of the significand,
5349             # the sign of the exponent, and the absolute value of the exponent. Both the
5350             # significand and the exponent are in base 10.
5351             #
5352             # Perl accepts literals like the following. The value is 100.1.
5353             #
5354             # 1__0__.__0__1__e+0__1__ (prints "Misplaced _ in number")
5355             # 1_0.0_1e+0_1
5356             #
5357             # Strings representing decimal numbers do not allow underscores, so only the
5358             # following is valid
5359             #
5360             # "10.01e+01"
5361              
5362             sub _dec_str_to_dec_str_parts {
5363 9785     9785   14083 my $class = shift;
5364 9785         15800 my $str = shift;
5365              
5366 9785 100       51759 if ($str =~ /
5367             ^
5368              
5369             # optional leading whitespace
5370             \s*
5371              
5372             # optional sign
5373             ( [+-]? )
5374              
5375             # significand
5376             (
5377             # integer part and optional fraction part ...
5378             \d+ (?: _+ \d+ )* _*
5379             (?:
5380             \.
5381             (?: _* \d+ (?: _+ \d+ )* _* )?
5382             )?
5383             |
5384             # ... or mandatory fraction part
5385             \.
5386             \d+ (?: _+ \d+ )* _*
5387             )
5388              
5389             # optional exponent
5390             (?:
5391             [Ee]
5392             ( [+-]? )
5393             ( \d+ (?: _+ \d+ )* _* )
5394             )?
5395              
5396             # optional trailing whitespace
5397             \s*
5398              
5399             $
5400             /x)
5401             {
5402 8695         25952 return $class -> _trim_split_parts($1, $2, $3, $4);
5403             }
5404              
5405 1090         3245 return;
5406             }
5407              
5408             # Takes any string representing a valid hexadecimal number and splits it into
5409             # four strings: the sign of the significand, the absolute value of the
5410             # significand, the sign of the exponent, and the absolute value of the exponent.
5411             # The significand is in base 16, and the exponent is in base 2.
5412             #
5413             # Perl accepts literals like the following. The "x" might be a capital "X". The
5414             # value is 32.0078125.
5415             #
5416             # 0x__1__0__.0__1__p+0__1__ (prints "Misplaced _ in number")
5417             # 0x1_0.0_1p+0_1
5418             #
5419             # The CORE::hex() function does not accept floating point accepts
5420             #
5421             # "0x_1_0"
5422             # "x_1_0"
5423             # "_1_0"
5424              
5425             sub _hex_str_to_hex_str_parts {
5426 1118     1118   1662 my $class = shift;
5427 1118         1522 my $str = shift;
5428              
5429 1118 100       6296 if ($str =~ /
5430             ^
5431              
5432             # optional leading whitespace
5433             \s*
5434              
5435             # optional sign
5436             ( [+-]? )
5437              
5438             # optional hex prefix
5439             (?: 0? [Xx] _* )?
5440              
5441             # significand using the hex digits 0..9 and a..f
5442             (
5443             # integer part and optional fraction part ...
5444             [0-9a-fA-F]+ (?: _+ [0-9a-fA-F]+ )* _*
5445             (?:
5446             \.
5447             (?: _* [0-9a-fA-F]+ (?: _+ [0-9a-fA-F]+ )* _* )?
5448             )?
5449             |
5450             # ... or mandatory fraction part
5451             \.
5452             [0-9a-fA-F]+ (?: _+ [0-9a-fA-F]+ )* _*
5453             )
5454              
5455             # optional exponent (power of 2) using decimal digits
5456             (?:
5457             [Pp]
5458             ( [+-]? )
5459             ( \d+ (?: _+ \d+ )* _* )
5460             )?
5461              
5462             # optional trailing whitespace
5463             \s*
5464              
5465             $
5466             /x)
5467             {
5468 1114         2966 return $class -> _trim_split_parts($1, $2, $3, $4);
5469             }
5470              
5471 4         17 return;
5472             }
5473              
5474             # Takes any string representing a valid octal number and splits it into four
5475             # strings: the sign of the significand, the absolute value of the significand,
5476             # the sign of the exponent, and the absolute value of the exponent. The
5477             # significand is in base 8, and the exponent is in base 2.
5478              
5479             sub _oct_str_to_oct_str_parts {
5480 3     3   8 my $class = shift;
5481 3         5 my $str = shift;
5482              
5483 3 50       34 if ($str =~ /
5484             ^
5485              
5486             # optional leading whitespace
5487             \s*
5488              
5489             # optional sign
5490             ( [+-]? )
5491              
5492             # optional octal prefix
5493             (?: 0? [Oo] _* )?
5494              
5495             # significand using the octal digits 0..7
5496             (
5497             # integer part and optional fraction part ...
5498             [0-7]+ (?: _+ [0-7]+ )* _*
5499             (?:
5500             \.
5501             (?: _* [0-7]+ (?: _+ [0-7]+ )* _* )?
5502             )?
5503             |
5504             # ... or mandatory fraction part
5505             \.
5506             [0-7]+ (?: _+ [0-7]+ )* _*
5507             )
5508              
5509             # optional exponent (power of 2) using decimal digits
5510             (?:
5511             [Pp]
5512             ( [+-]? )
5513             ( \d+ (?: _+ \d+ )* _* )
5514             )?
5515              
5516             # optional trailing whitespace
5517             \s*
5518              
5519             $
5520             /x)
5521             {
5522 3         12 return $class -> _trim_split_parts($1, $2, $3, $4);
5523             }
5524              
5525 0         0 return;
5526             }
5527              
5528             # Takes any string representing a valid binary number and splits it into four
5529             # strings: the sign of the significand, the absolute value of the significand,
5530             # the sign of the exponent, and the absolute value of the exponent. The
5531             # significand is in base 2, and the exponent is in base 2.
5532              
5533             sub _bin_str_to_bin_str_parts {
5534 275     275   414 my $class = shift;
5535 275         409 my $str = shift;
5536              
5537 275 100       1784 if ($str =~ /
5538             ^
5539              
5540             # optional leading whitespace
5541             \s*
5542              
5543             # optional sign
5544             ( [+-]? )
5545              
5546             # optional binary prefix
5547             (?: 0? [Bb] _* )?
5548              
5549             # significand using the binary digits 0 and 1
5550             (
5551             # integer part and optional fraction part ...
5552             [01]+ (?: _+ [01]+ )* _*
5553             (?:
5554             \.
5555             (?: _* [01]+ (?: _+ [01]+ )* _* )?
5556             )?
5557             |
5558             # ... or mandatory fraction part
5559             \.
5560             [01]+ (?: _+ [01]+ )* _*
5561             )
5562              
5563             # optional exponent (power of 2) using decimal digits
5564             (?:
5565             [Pp]
5566             ( [+-]? )
5567             ( \d+ (?: _+ \d+ )* _* )
5568             )?
5569              
5570             # optional trailing whitespace
5571             \s*
5572              
5573             $
5574             /x)
5575             {
5576 252         825 return $class -> _trim_split_parts($1, $2, $3, $4);
5577             }
5578              
5579 23         121 return;
5580             }
5581              
5582             # Takes any string representing a valid decimal number and splits it into four
5583             # parts: the sign of the significand, the absolute value of the significand as a
5584             # libray thingy, the sign of the exponent, and the absolute value of the
5585             # exponent as a library thingy.
5586              
5587             sub _dec_str_parts_to_flt_lib_parts {
5588 8695     8695   12612 shift; # class name
5589              
5590 8695         19609 my ($sig_sgn, $sig_str, $exp_sgn, $exp_str) = @_;
5591              
5592             # Handle zero.
5593              
5594 8695 100       18026 if ($sig_str eq '0') {
5595 4744         15720 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
5596             }
5597              
5598             # Absolute value of exponent as library "object".
5599              
5600 3951         14305 my $exp_lib = $LIB -> _new($exp_str);
5601              
5602             # If there is a dot in the significand, remove it so the significand
5603             # becomes an integer and adjust the exponent accordingly. Also remove
5604             # leading zeros which might now appear in the significand. E.g.,
5605             #
5606             # 12.345e-2 -> 12345e-5
5607             # 12.345e+2 -> 12345e-1
5608             # 0.0123e+5 -> 00123e+1 -> 123e+1
5609              
5610 3951         8847 my $idx = index $sig_str, '.';
5611 3951 100       9211 if ($idx >= 0) {
5612 2324         5659 substr($sig_str, $idx, 1) = '';
5613              
5614             # delta = length - index
5615 2324         6015 my $delta = $LIB -> _new(CORE::length($sig_str));
5616 2324         6463 $delta = $LIB -> _sub($delta, $LIB -> _new($idx));
5617              
5618             # exponent - delta
5619 2324         10353 ($exp_lib, $exp_sgn) = $LIB -> _ssub($exp_lib, $exp_sgn, $delta, '+');
5620              
5621 2324         7571 $sig_str =~ s/^0+//;
5622             }
5623              
5624             # If there are trailing zeros in the significand, remove them and
5625             # adjust the exponent. E.g.,
5626             #
5627             # 12340e-5 -> 1234e-4
5628             # 12340e-1 -> 1234e0
5629             # 12340e+3 -> 1234e4
5630              
5631 3951 100       12219 if ($sig_str =~ s/(0+)\z//) {
5632 863         2073 my $len = CORE::length($1);
5633 863         2338 ($exp_lib, $exp_sgn) =
5634             $LIB -> _sadd($exp_lib, $exp_sgn, $LIB -> _new($len), '+');
5635             }
5636              
5637             # At this point, the significand is empty or an integer with no trailing
5638             # zeros. The exponent is in base 10.
5639              
5640 3951 50       9334 unless (CORE::length $sig_str) {
5641 0         0 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
5642             }
5643              
5644             # Absolute value of significand as library "object".
5645              
5646 3951         9663 my $sig_lib = $LIB -> _new($sig_str);
5647              
5648 3951         25574 return $sig_sgn, $sig_lib, $exp_sgn, $exp_lib;
5649             }
5650              
5651             # Takes any string representing a valid binary number and splits it into four
5652             # parts: the sign of the significand, the absolute value of the significand as a
5653             # libray thingy, the sign of the exponent, and the absolute value of the
5654             # exponent as a library thingy.
5655              
5656             sub _bin_str_parts_to_flt_lib_parts {
5657 1369     1369   1926 shift; # class name
5658              
5659 1369         3065 my ($sig_sgn, $sig_str, $exp_sgn, $exp_str, $bpc) = @_;
5660 1369         4553 my $bpc_lib = $LIB -> _new($bpc);
5661              
5662             # Handle zero.
5663              
5664 1369 100       3112 if ($sig_str eq '0') {
5665 12         39 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
5666             }
5667              
5668             # Absolute value of exponent as library "object".
5669              
5670 1357         2969 my $exp_lib = $LIB -> _new($exp_str);
5671              
5672             # If there is a dot in the significand, remove it so the significand
5673             # becomes an integer and adjust the exponent accordingly. Also remove
5674             # leading zeros which might now appear in the significand. E.g., with
5675             # hexadecimal numbers
5676             #
5677             # 12.345p-2 -> 12345p-14
5678             # 12.345p+2 -> 12345p-10
5679             # 0.0123p+5 -> 00123p-11 -> 123p-11
5680              
5681 1357         3036 my $idx = index $sig_str, '.';
5682 1357 100       2780 if ($idx >= 0) {
5683 3         7 substr($sig_str, $idx, 1) = '';
5684              
5685             # delta = (length - index) * bpc
5686 3         7 my $delta = $LIB -> _new(CORE::length($sig_str));
5687 3         8 $delta = $LIB -> _sub($delta, $LIB -> _new($idx));
5688 3 100       16 $delta = $LIB -> _mul($delta, $bpc_lib) if $bpc != 1;
5689              
5690             # exponent - delta
5691 3         12 ($exp_lib, $exp_sgn) = $LIB -> _ssub($exp_lib, $exp_sgn, $delta, '+');
5692              
5693 3         11 $sig_str =~ s/^0+//;
5694             }
5695              
5696             # If there are trailing zeros in the significand, remove them and
5697             # adjust the exponent accordingly. E.g., with hexadecimal numbers
5698             #
5699             # 12340p-5 -> 1234p-1
5700             # 12340p-1 -> 1234p+3
5701             # 12340p+3 -> 1234p+7
5702              
5703 1357 100       4718 if ($sig_str =~ s/(0+)\z//) {
5704              
5705             # delta = length * bpc
5706 241         800 my $delta = $LIB -> _new(CORE::length($1));
5707 241 100       900 $delta = $LIB -> _mul($delta, $bpc_lib) if $bpc != 1;
5708              
5709             # exponent + delta
5710 241         827 ($exp_lib, $exp_sgn) = $LIB -> _sadd($exp_lib, $exp_sgn, $delta, '+');
5711             }
5712              
5713             # At this point, the significand is empty or an integer with no leading
5714             # or trailing zeros. The exponent is in base 2.
5715              
5716 1357 50       2927 unless (CORE::length $sig_str) {
5717 0         0 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
5718             }
5719              
5720             # Absolute value of significand as library "object".
5721              
5722 1357 50       7192 my $sig_lib = $bpc == 1 ? $LIB -> _from_bin('0b' . $sig_str)
    100          
    100          
5723             : $bpc == 3 ? $LIB -> _from_oct('0' . $sig_str)
5724             : $bpc == 4 ? $LIB -> _from_hex('0x' . $sig_str)
5725             : die "internal error: invalid exponent multiplier";
5726              
5727             # If the exponent (in base 2) is positive or zero ...
5728              
5729 1357 100       2942 if ($exp_sgn eq '+') {
5730              
5731 1356 100       3642 if (!$LIB -> _is_zero($exp_lib)) {
5732              
5733             # Multiply significand by 2 raised to the exponent.
5734              
5735 242         624 my $p = $LIB -> _pow($LIB -> _two(), $exp_lib);
5736 242         616 $sig_lib = $LIB -> _mul($sig_lib, $p);
5737 242         569 $exp_lib = $LIB -> _zero();
5738             }
5739             }
5740              
5741             # ... else if the exponent is negative ...
5742              
5743             else {
5744              
5745             # Rather than dividing the significand by 2 raised to the absolute
5746             # value of the exponent, multiply the significand by 5 raised to the
5747             # absolute value of the exponent and let the exponent be in base 10:
5748             #
5749             # a * 2^(-b) = a * 5^b * 10^(-b) = c * 10^(-b), where c = a * 5^b
5750              
5751 1         4 my $p = $LIB -> _pow($LIB -> _new("5"), $exp_lib);
5752 1         3 $sig_lib = $LIB -> _mul($sig_lib, $p);
5753             }
5754              
5755             # Adjust for the case when the conversion to decimal introduced trailing
5756             # zeros in the significand.
5757              
5758 1357         3487 my $n = $LIB -> _zeros($sig_lib);
5759 1357 100       2883 if ($n) {
5760 213         571 $n = $LIB -> _new($n);
5761 213         703 $sig_lib = $LIB -> _rsft($sig_lib, $n, 10);
5762 213         711 ($exp_lib, $exp_sgn) = $LIB -> _sadd($exp_lib, $exp_sgn, $n, '+');
5763             }
5764              
5765 1357         8428 return $sig_sgn, $sig_lib, $exp_sgn, $exp_lib;
5766             }
5767              
5768             # Takes any string representing a valid hexadecimal number and splits it into
5769             # four parts: the sign of the significand, the absolute value of the significand
5770             # as a libray thingy, the sign of the exponent, and the absolute value of the
5771             # exponent as a library thingy.
5772              
5773             sub _hex_str_to_flt_lib_parts {
5774 1118     1118   1992 my $class = shift;
5775 1118         1631 my $str = shift;
5776 1118 100       2793 if (my @parts = $class -> _hex_str_to_hex_str_parts($str)) {
5777 1114         2929 return $class -> _bin_str_parts_to_flt_lib_parts(@parts, 4); # 4 bits pr. chr
5778             }
5779 4         42 return;
5780             }
5781              
5782             # Takes any string representing a valid octal number and splits it into four
5783             # parts: the sign of the significand, the absolute value of the significand as a
5784             # libray thingy, the sign of the exponent, and the absolute value of the
5785             # exponent as a library thingy.
5786              
5787             sub _oct_str_to_flt_lib_parts {
5788 3     3   9 my $class = shift;
5789 3         7 my $str = shift;
5790 3 50       11 if (my @parts = $class -> _oct_str_to_oct_str_parts($str)) {
5791 3         12 return $class -> _bin_str_parts_to_flt_lib_parts(@parts, 3); # 3 bits pr. chr
5792             }
5793 0         0 return;
5794             }
5795              
5796             # Takes any string representing a valid binary number and splits it into four
5797             # parts: the sign of the significand, the absolute value of the significand as a
5798             # libray thingy, the sign of the exponent, and the absolute value of the
5799             # exponent as a library thingy.
5800              
5801             sub _bin_str_to_flt_lib_parts {
5802 275     275   499 my $class = shift;
5803 275         424 my $str = shift;
5804 275 100       730 if (my @parts = $class -> _bin_str_to_bin_str_parts($str)) {
5805 252         764 return $class -> _bin_str_parts_to_flt_lib_parts(@parts, 1); # 1 bit pr. chr
5806             }
5807 23         108 return;
5808             }
5809              
5810             # Decimal string is split into the sign of the signficant, the absolute value of
5811             # the significand as library thingy, the sign of the exponent, and the absolute
5812             # value of the exponent as a a library thingy.
5813              
5814             sub _dec_str_to_flt_lib_parts {
5815 9785     9785   18071 my $class = shift;
5816 9785         14835 my $str = shift;
5817 9785 100       25307 if (my @parts = $class -> _dec_str_to_dec_str_parts($str)) {
5818 8695         23283 return $class -> _dec_str_parts_to_flt_lib_parts(@parts);
5819             }
5820 1090         5567 return;
5821             }
5822              
5823             # Hexdecimal string to a string using decimal floating point notation.
5824              
5825             sub hex_str_to_dec_flt_str {
5826 0     0 1   my $class = shift;
5827 0           my $str = shift;
5828 0 0         if (my @parts = $class -> _hex_str_to_flt_lib_parts($str)) {
5829 0           return $class -> _flt_lib_parts_to_flt_str(@parts);
5830             }
5831 0           return;
5832             }
5833              
5834             # Octal string to a string using decimal floating point notation.
5835              
5836             sub oct_str_to_dec_flt_str {
5837 0     0 1   my $class = shift;
5838 0           my $str = shift;
5839 0 0         if (my @parts = $class -> _oct_str_to_flt_lib_parts($str)) {
5840 0           return $class -> _flt_lib_parts_to_flt_str(@parts);
5841             }
5842 0           return;
5843             }
5844              
5845             # Binary string to a string decimal floating point notation.
5846              
5847             sub bin_str_to_dec_flt_str {
5848 0     0 1   my $class = shift;
5849 0           my $str = shift;
5850 0 0         if (my @parts = $class -> _bin_str_to_flt_lib_parts($str)) {
5851 0           return $class -> _flt_lib_parts_to_flt_str(@parts);
5852             }
5853 0           return;
5854             }
5855              
5856             # Decimal string to a string using decimal floating point notation.
5857              
5858             sub dec_str_to_dec_flt_str {
5859 0     0 1   my $class = shift;
5860 0           my $str = shift;
5861 0 0         if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
5862 0           return $class -> _flt_lib_parts_to_flt_str(@parts);
5863             }
5864 0           return;
5865             }
5866              
5867             # Hexdecimal string to decimal notation (no exponent).
5868              
5869             sub hex_str_to_dec_str {
5870 0     0 1   my $class = shift;
5871 0           my $str = shift;
5872 0 0         if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
5873 0           return $class -> _flt_lib_parts_to_dec_str(@parts);
5874             }
5875 0           return;
5876             }
5877              
5878             # Octal string to decimal notation (no exponent).
5879              
5880             sub oct_str_to_dec_str {
5881 0     0 1   my $class = shift;
5882 0           my $str = shift;
5883 0 0         if (my @parts = $class -> _oct_str_to_flt_lib_parts($str)) {
5884 0           return $class -> _flt_lib_parts_to_dec_str(@parts);
5885             }
5886 0           return;
5887             }
5888              
5889             # Binary string to decimal notation (no exponent).
5890              
5891             sub bin_str_to_dec_str {
5892 0     0 1   my $class = shift;
5893 0           my $str = shift;
5894 0 0         if (my @parts = $class -> _bin_str_to_flt_lib_parts($str)) {
5895 0           return $class -> _flt_lib_parts_to_dec_str(@parts);
5896             }
5897 0           return;
5898             }
5899              
5900             # Decimal string to decimal notation (no exponent).
5901              
5902             sub dec_str_to_dec_str {
5903 0     0 1   my $class = shift;
5904 0           my $str = shift;
5905 0 0         if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
5906 0           return $class -> _flt_lib_parts_to_dec_str(@parts);
5907             }
5908 0           return;
5909             }
5910              
5911             sub _flt_lib_parts_to_flt_str {
5912 0     0     my $class = shift;
5913 0           my @parts = @_;
5914 0           return $parts[0] . $LIB -> _str($parts[1])
5915             . 'e' . $parts[2] . $LIB -> _str($parts[3]);
5916             }
5917              
5918             sub _flt_lib_parts_to_dec_str {
5919 0     0     my $class = shift;
5920 0           my @parts = @_;
5921              
5922             # The number is an integer iff the exponent is non-negative.
5923              
5924 0 0         if ($parts[2] eq '+') {
5925 0           my $str = $parts[0]
5926             . $LIB -> _str($LIB -> _lsft($parts[1], $parts[3], 10));
5927 0           return $str;
5928             }
5929              
5930             # If it is not an integer, add a decimal point.
5931              
5932             else {
5933 0           my $mant = $LIB -> _str($parts[1]);
5934 0           my $mant_len = CORE::length($mant);
5935 0           my $expo = $LIB -> _num($parts[3]);
5936 0           my $len_cmp = $mant_len <=> $expo;
5937 0 0         if ($len_cmp <= 0) {
5938 0           return $parts[0] . '0.' . '0' x ($expo - $mant_len) . $mant;
5939             } else {
5940 0           substr $mant, $mant_len - $expo, 0, '.';
5941 0           return $parts[0] . $mant;
5942             }
5943             }
5944             }
5945              
5946             # Takes four arguments, the sign of the significand, the absolute value of the
5947             # significand as a libray thingy, the sign of the exponent, and the absolute
5948             # value of the exponent as a library thingy, and returns three parts: the sign
5949             # of the rational number, the absolute value of the numerator as a libray
5950             # thingy, and the absolute value of the denominator as a library thingy.
5951             #
5952             # For example, to convert data representing the value "+12e-2", then
5953             #
5954             # $sm = "+";
5955             # $m = $LIB -> _new("12");
5956             # $se = "-";
5957             # $e = $LIB -> _new("2");
5958             # ($sr, $n, $d) = $class -> _flt_lib_parts_to_rat_lib_parts($sm, $m, $se, $e);
5959             #
5960             # returns data representing the same value written as the fraction "+3/25"
5961             #
5962             # $sr = "+"
5963             # $n = $LIB -> _new("3");
5964             # $d = $LIB -> _new("12");
5965              
5966             sub _flt_lib_parts_to_rat_lib_parts {
5967 0     0     my $self = shift;
5968 0           my ($msgn, $mabs, $esgn, $eabs) = @_;
5969              
5970 0 0         if ($esgn eq '-') { # "12e-2" -> "12/100" -> "3/25"
    0          
5971 0           my $num_lib = $LIB -> _copy($mabs);
5972 0           my $den_lib = $LIB -> _1ex($LIB -> _num($eabs));
5973 0           my $gcd_lib = $LIB -> _gcd($LIB -> _copy($num_lib), $den_lib);
5974 0           $num_lib = $LIB -> _div($LIB -> _copy($num_lib), $gcd_lib);
5975 0           $den_lib = $LIB -> _div($den_lib, $gcd_lib);
5976 0           return $msgn, $num_lib, $den_lib;
5977             }
5978              
5979             elsif (!$LIB -> _is_zero($eabs)) { # "12e+2" -> "1200" -> "1200/1"
5980 0           return $msgn, $LIB -> _lsft($LIB -> _copy($mabs), $eabs, 10),
5981             $LIB -> _one();
5982             }
5983              
5984             else { # "12e+0" -> "12" -> "12/1"
5985 0           return $msgn, $mabs, $LIB -> _one();
5986             }
5987             }
5988              
5989             # Add the function _register_callback() to Math::BigInt. It is provided for
5990             # backwards compabibility so that old version of Math::BigRat etc. don't
5991             # complain about missing it.
5992              
5993       0     sub _register_callback { }
5994              
5995             ###############################################################################
5996             # this method returns 0 if the object can be modified, or 1 if not.
5997             # We use a fast constant sub() here, to avoid costly calls. Subclasses
5998             # may override it with special code (f.i. Math::BigInt::Constant does so)
5999              
6000             sub modify () { 0; }
6001              
6002             1;
6003              
6004             __END__