File Coverage

blib/lib/Math/BigInt.pm
Criterion Covered Total %
statement 1738 2709 64.1
branch 1352 2528 53.4
condition 610 1055 57.8
subroutine 191 254 75.2
pod 149 151 98.6
total 4040 6697 60.3


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             #
12             # sign : "+", "-", "+inf", "-inf", or "NaN"
13             # value : unsigned int with actual value ($LIB thingy)
14             # accuracy : accuracy (scalar)
15             # precision : precision (scalar)
16              
17             # Remember not to take shortcuts ala $xs = $x->{value}; $LIB->foo($xs); since
18             # underlying lib might change the reference!
19              
20 50     50   4478113 use 5.006001;
  50         202  
21 50     50   417 use strict;
  50         217  
  50         1807  
22 50     50   250 use warnings;
  50         105  
  50         3367  
23              
24 50     50   312 use Carp qw< carp croak >;
  50         195  
  50         4407  
25 50     50   360 use Scalar::Util qw< blessed refaddr >;
  50         118  
  50         94733  
26              
27             our $VERSION = '2.005003';
28             $VERSION =~ tr/_//d;
29              
30             require Exporter;
31             our @ISA = qw< Exporter >;
32             our @EXPORT_OK = qw< objectify bgcd blcm >;
33              
34             # Inside overload, the first arg is always an object. If the original code had
35             # it reversed (like $x = 2 * $y), then the third parameter is true.
36             # In some cases (like add, $x = $x + 2 is the same as $x = 2 + $x) this makes
37             # no difference, but in some cases it does.
38              
39             # For overloaded ops with only one argument we simple use $_[0]->copy() to
40             # preserve the argument.
41              
42             # Thus inheritance of overload operators becomes possible and transparent for
43             # our subclasses without the need to repeat the entire overload section there.
44              
45             use overload
46              
47             # overload key: with_assign
48              
49 307     307   1360 '+' => sub { $_[0] -> copy() -> badd($_[1]); },
50              
51 354     354   2857 '-' => sub { my $c = $_[0] -> copy();
52 354 100       1712 $_[2] ? $c -> bneg() -> badd($_[1])
53             : $c -> bsub($_[1]); },
54              
55 832     832   6564 '*' => sub { $_[0] -> copy() -> bmul($_[1]); },
56              
57 339 100   339   2240 '/' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bdiv($_[0])
58             : $_[0] -> copy() -> bdiv($_[1]); },
59              
60 353 100   353   6364 '%' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bmod($_[0])
61             : $_[0] -> copy() -> bmod($_[1]); },
62              
63 439 100   439   10604 '**' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bpow($_[0])
64             : $_[0] -> copy() -> bpow($_[1]); },
65              
66 20 50   20   681 '<<' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bblsft($_[0])
67             : $_[0] -> copy() -> bblsft($_[1]); },
68              
69 20 50   20   320 '>>' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bbrsft($_[0])
70             : $_[0] -> copy() -> bbrsft($_[1]); },
71              
72             # overload key: assign
73              
74 27     27   1489 '+=' => sub { $_[0] -> badd($_[1]); },
75              
76 29     29   1548 '-=' => sub { $_[0] -> bsub($_[1]); },
77              
78 17     17   305 '*=' => sub { $_[0] -> bmul($_[1]); },
79              
80 14     14   240 '/=' => sub { scalar $_[0] -> bdiv($_[1]); },
81              
82 17     17   328 '%=' => sub { $_[0] -> bmod($_[1]); },
83              
84 6     6   124 '**=' => sub { $_[0] -> bpow($_[1]); },
85              
86 3     3   48 '<<=' => sub { $_[0] -> bblsft($_[1]); },
87              
88 3     3   24 '>>=' => sub { $_[0] -> bbrsft($_[1]); },
89              
90             # 'x=' => sub { },
91              
92             # '.=' => sub { },
93              
94             # overload key: num_comparison
95              
96 318 50   318   1760 '<' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> blt($_[0])
97             : $_[0] -> blt($_[1]); },
98              
99 618 100   618   5717 '<=' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> ble($_[0])
100             : $_[0] -> ble($_[1]); },
101              
102 506 50   506   2285 '>' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bgt($_[0])
103             : $_[0] -> bgt($_[1]); },
104              
105 140 50   140   12840 '>=' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bge($_[0])
106             : $_[0] -> bge($_[1]); },
107              
108 294     294   191856 '==' => sub { $_[0] -> beq($_[1]); },
109              
110 9     9   728 '!=' => sub { $_[0] -> bne($_[1]); },
111              
112             # overload key: 3way_comparison
113              
114 0     0   0 '<=>' => sub { my $cmp = $_[0] -> bcmp($_[1]);
115 0 0 0     0 defined($cmp) && $_[2] ? -$cmp : $cmp; },
116              
117 8098 50   8098   4288360 'cmp' => sub { $_[2] ? "$_[1]" cmp $_[0] -> bstr()
118             : $_[0] -> bstr() cmp "$_[1]"; },
119              
120             # overload key: str_comparison
121              
122             # 'lt' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrlt($_[0])
123             # : $_[0] -> bstrlt($_[1]); },
124             #
125             # 'le' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrle($_[0])
126             # : $_[0] -> bstrle($_[1]); },
127             #
128             # 'gt' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrgt($_[0])
129             # : $_[0] -> bstrgt($_[1]); },
130             #
131             # 'ge' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bstrge($_[0])
132             # : $_[0] -> bstrge($_[1]); },
133             #
134             # 'eq' => sub { $_[0] -> bstreq($_[1]); },
135             #
136             # 'ne' => sub { $_[0] -> bstrne($_[1]); },
137              
138             # overload key: binary
139              
140 140 100   140   2203 '&' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> band($_[0])
141             : $_[0] -> copy() -> band($_[1]); },
142              
143 4     4   85 '&=' => sub { $_[0] -> band($_[1]); },
144              
145 201 100   201   6906 '|' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bior($_[0])
146             : $_[0] -> copy() -> bior($_[1]); },
147              
148 4     4   81 '|=' => sub { $_[0] -> bior($_[1]); },
149              
150 199 100   199   3398 '^' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> bxor($_[0])
151             : $_[0] -> copy() -> bxor($_[1]); },
152              
153 4     4   87 '^=' => sub { $_[0] -> bxor($_[1]); },
154              
155             # '&.' => sub { },
156              
157             # '&.=' => sub { },
158              
159             # '|.' => sub { },
160              
161             # '|.=' => sub { },
162              
163             # '^.' => sub { },
164              
165             # '^.=' => sub { },
166              
167             # overload key: unary
168              
169 285     285   1886 'neg' => sub { $_[0] -> copy() -> bneg(); },
170              
171             # '!' => sub { },
172              
173 0     0   0 '~' => sub { $_[0] -> copy() -> bnot(); },
174              
175             # '~.' => sub { },
176              
177             # overload key: mutators
178              
179 22     22   211 '++' => sub { $_[0] -> binc() },
180              
181 3     3   35 '--' => sub { $_[0] -> bdec() },
182              
183             # overload key: func
184              
185 0 0   0   0 'atan2' => sub { $_[2] ? ref($_[0]) -> new($_[1]) -> batan2($_[0])
186             : $_[0] -> copy() -> batan2($_[1]); },
187              
188 0     0   0 'cos' => sub { $_[0] -> copy() -> bcos(); },
189              
190 0     0   0 'sin' => sub { $_[0] -> copy() -> bsin(); },
191              
192 0     0   0 'exp' => sub { $_[0] -> copy() -> bexp($_[1]); },
193              
194 3     3   48 'abs' => sub { $_[0] -> copy() -> babs(); },
195              
196 30     30   607 'log' => sub { $_[0] -> copy() -> blog(); },
197              
198 1     1   9 'sqrt' => sub { $_[0] -> copy() -> bsqrt(); },
199              
200 6     6   50 'int' => sub { $_[0] -> copy() -> bint(); },
201              
202             # overload key: conversion
203              
204 6 100   6   115 'bool' => sub { $_[0] -> is_zero() ? '' : 1; },
205              
206 1896     1896   6556 '""' => sub { $_[0] -> bstr(); },
207              
208 51     51   446 '0+' => sub { $_[0] -> numify(); },
209              
210 0     0   0 '=' => sub { $_[0] -> copy(); },
211              
212 50     50   30349 ;
  50         88399  
  50         4144  
213              
214             ##############################################################################
215             # global constants, flags and accessory
216              
217             # These vars are public, but their direct usage is not recommended, use the
218             # accessor methods instead
219              
220             our $accuracy = undef;
221             our $precision = undef;
222              
223             our $round_mode = 'even'; # even, odd, +inf, -inf, zero, trunc, common
224             our $div_scale = 40;
225              
226             our $upgrade = undef;
227             our $downgrade = undef;
228              
229             our $_trap_nan = 0; # croak on NaNs?
230             our $_trap_inf = 0; # croak on Infs?
231              
232             my $nan = 'NaN'; # constant 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? This variable is 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 50     50   161 my ($class) = @_;
250 50         261 bless \$round_mode, $class;
251             }
252              
253             sub FETCH {
254 3     3   72 return $round_mode;
255             }
256              
257             sub STORE {
258 51     51   885 $rnd_mode = (ref $_[0]) -> round_mode($_[1]);
259             }
260              
261             BEGIN {
262             # tie to enable $rnd_mode to work transparently
263 50     50   44476 tie $rnd_mode, 'Math::BigInt';
264              
265             # set up some handy alias names
266 50         375 *is_pos = \&is_positive;
267 50         367 *is_neg = \&is_negative;
268 50         18730 *as_number = \&as_int;
269             }
270              
271             ###############################################################################
272             # Configuration methods
273             ###############################################################################
274              
275             sub accuracy {
276 77426     77426 1 639606 my $x = shift;
277 77426   50     290226 my $class = ref($x) || $x || __PACKAGE__;
278              
279             # setter/mutator
280              
281 77426 100       156402 if (@_) {
282 1205         2504 my $a = shift;
283              
284 1205 100       3757 if (defined $a) {
285 503 0       1488 $a = $a -> can('numify') ? $a -> numify() : 0 + "$a" if ref($a);
    50          
286 503 50       3854 croak "accuracy must be a number, not '$a'"
287             if $a !~ /^\s*[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\s*\z/;
288 503 50       1754 croak "accuracy must be an integer, not '$a'"
289             if $a != int $a;
290             }
291              
292 1205 100       2910 if (ref($x)) {
293 518 100       2834 $x -> bround($a) if defined $a;
294 518         1720 $x -> {precision} = undef; # clear instance P
295 518         4524 $x -> {accuracy} = $a; # set instance A
296             } else {
297 50     50   454 no strict 'refs';
  50         118  
  50         6411  
298 687         1276 ${"${class}::precision"} = undef; # clear class P
  687         2455  
299 687         1124 ${"${class}::accuracy"} = $a; # set class A
  687         2418  
300             }
301             }
302              
303             # getter/accessor
304              
305             else {
306 76221 100       141200 if (ref($x)) {
307 113         1099 return $x -> {accuracy};
308             } else {
309 50     50   369 no strict 'refs';
  50         126  
  50         21239  
310 76108         117457 return ${"${class}::accuracy"};
  76108         342044  
311             }
312             }
313             }
314              
315             sub precision {
316 87290     87290 1 154555 my $x = shift;
317 87290   50     311905 my $class = ref($x) || $x || __PACKAGE__;
318              
319             # setter/mutator
320              
321 87290 100       165096 if (@_) {
322 1285         2559 my $p = shift;
323              
324 1285 100       3790 if (defined $p) {
325 230 0       713 $p = $p -> can('numify') ? $p -> numify() : 0 + "$p" if ref($p);
    50          
326 230 50       1909 croak "precision must be a number, not '$p'"
327             if $p !~ /^\s*[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\s*\z/;
328 230 50       863 croak "precision must be an integer, not '$p'"
329             if $p != int $p;
330             }
331              
332 1285 100       3172 if (ref($x)) {
333 219 100       1206 $x -> bfround($p) if defined $p;
334 219         550 $x -> {accuracy} = undef; # clear instance A
335 219         2942 $x -> {precision} = $p; # set instance P
336             } else {
337 50     50   426 no strict 'refs';
  50         107  
  50         5352  
338 1066         1911 ${"${class}::accuracy"} = undef; # clear class A
  1066         3995  
339 1066         1963 ${"${class}::precision"} = $p; # set class P
  1066         3931  
340             }
341             }
342              
343             # getter/accessor
344              
345             else {
346 86005 100       160886 if (ref($x)) {
347 114         1126 return $x -> {precision};
348             } else {
349 50     50   332 no strict 'refs';
  50         125  
  50         14270  
350 85891         121080 return ${"${class}::precision"};
  85891         282079  
351             }
352             }
353             }
354              
355             sub round_mode {
356 50622     50622 1 104139 my $self = shift;
357 50622   50     205838 my $class = ref($self) || $self || __PACKAGE__;
358              
359             # setter/mutator
360              
361 50622 100       108970 if (@_) {
362 382         670 my $m = shift;
363 382 50       947 croak("The value for 'round_mode' must be defined")
364             unless defined $m;
365 382 100       2999 croak("Unknown round mode '$m'")
366             unless $m =~ /^(even|odd|\+inf|\-inf|zero|trunc|common)$/;
367              
368 378 50 33     1339 if (ref($self) && exists $self -> {round_mode}) {
369 0         0 $self->{round_mode} = $m;
370             } else {
371 50     50   343 no strict 'refs';
  50         126  
  50         4175  
372 378         678 ${"${class}::round_mode"} = $m;
  378         5266  
373             }
374             }
375              
376             # getter/accessor
377              
378             else {
379 50240 50 66     132462 if (ref($self) && exists $self -> {round_mode}) {
380 0         0 return $self->{round_mode};
381             } else {
382 50     50   339 no strict 'refs';
  50         113  
  50         20668  
383 50240         82211 my $m = ${"${class}::round_mode"};
  50240         200311  
384 50240 50       163068 return defined($m) ? $m : $round_mode;
385             }
386             }
387             }
388              
389             sub div_scale {
390 1237     1237 1 2350 my $self = shift;
391 1237   50     6207 my $class = ref($self) || $self || __PACKAGE__;
392              
393             # setter/mutator
394              
395 1237 100       2891 if (@_) {
396 31         61 my $f = shift;
397 31 50       100 croak("The value for 'div_scale' must be defined") unless defined $f;
398 31 0       80 $f = $f -> can('numify') ? $f -> numify() : 0 + "$f" if ref($f);
    50          
399             # also croak on non-numerical
400 31 50       262 croak "div_scale must be a number, not '$f'"
401             unless $f =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
402 31 50       104 croak "div_scale must be an integer, not '$f'"
403             if $f != int $f;
404             # It is not documented what div_scale <= 0 means, but Astro::Units sets
405             # div_scale to 0 and fails its tests if this is not supported. So we
406             # silently support div_scale = 0.
407 31 50       78 croak "div_scale must be positive, not '$f'" if $f < 0;
408              
409 31 50 33     99 if (ref($self) && exists $self -> {div_scale}) {
410 0         0 $self -> {div_scale} = $f;
411             } else {
412 50     50   499 no strict 'refs';
  50         218  
  50         4549  
413 31         80 ${"${class}::div_scale"} = $f;
  31         237  
414             }
415             }
416              
417             # getter/accessor
418              
419             else {
420 1206 50 66     4004 if (ref($self) && exists $self -> {div_scale}) {
421 0         0 return $self -> {div_scale};
422             } else {
423 50     50   357 no strict 'refs';
  50         95  
  50         9985  
424 1206         1824 my $f = ${"${class}::div_scale"};
  1206         3834  
425 1206 50       4667 return defined($f) ? $f : $div_scale;
426             }
427             }
428             }
429              
430             sub trap_inf {
431 207     207 1 294 my $self = shift;
432 207   50     676 my $class = ref($self) || $self || __PACKAGE__;
433              
434             # setter/mutator
435              
436 207 100       365 if (@_) {
437 22 100       63 my $b = shift() ? 1 : 0;
438 22 50 33     89 if (ref($self) && exists $self -> {trap_inf}) {
439 0         0 $self -> {trap_inf} = $b;
440             } else {
441 50     50   398 no strict 'refs';
  50         129  
  50         4661  
442 22         38 ${"${class}::_trap_inf"} = $b;
  22         84  
443             }
444             }
445              
446             # getter/accessor
447              
448             else {
449 185 50 33     402 if (ref($self) && exists $self -> {trap_inf}) {
450 0         0 return $self -> {trap_inf};
451             } else {
452 50     50   328 no strict 'refs';
  50         117  
  50         7976  
453 185         231 return ${"${class}::_trap_inf"};
  185         893  
454             }
455             }
456             }
457              
458             sub trap_nan {
459 228     228 1 372 my $self = shift;
460 228   50     765 my $class = ref($self) || $self || __PACKAGE__;
461              
462             # setter/mutator
463              
464 228 100       387 if (@_) {
465 34 100       97 my $b = shift() ? 1 : 0;
466 34 50 33     121 if (ref($self) && exists $self -> {trap_nan}) {
467 0         0 $self -> {trap_nan} = $b;
468             } else {
469 50     50   371 no strict 'refs';
  50         161  
  50         5840  
470 34         53 ${"${class}::_trap_nan"} = $b;
  34         162  
471             }
472             }
473              
474             # getter/accessor
475              
476             else {
477 194 50 33     402 if (ref($self) && exists $self -> {trap_nan}) {
478 0         0 return $self -> {trap_nan};
479             } else {
480 50     50   307 no strict 'refs';
  50         105  
  50         7926  
481 194         242 return ${"${class}::_trap_nan"};
  194         902  
482             }
483             }
484             }
485              
486             sub upgrade {
487 80711     80711 1 323121 my $self = shift;
488 80711   50     293447 my $class = ref($self) || $self || __PACKAGE__;
489              
490             # setter/mutator
491              
492 80711 100       158670 if (@_) {
493 15126         21688 my $u = shift;
494 15126 50 33     38177 if (ref($self) && exists $self -> {upgrade}) {
495 0         0 $self -> {upgrade} = $u;
496             } else {
497 50     50   356 no strict 'refs';
  50         95  
  50         4402  
498 15126         20127 ${"${class}::upgrade"} = $u;
  15126         42537  
499             }
500             }
501              
502             # getter/accessor
503              
504             else {
505 65585 50 33     158044 if (ref($self) && exists $self -> {upgrade}) {
506 0         0 return $self -> {upgrade};
507             } else {
508 50     50   324 no strict 'refs';
  50         134  
  50         7518  
509 65585         90212 return ${"${class}::upgrade"};
  65585         331403  
510             }
511             }
512             }
513              
514             sub downgrade {
515 148273     148273 1 746273 my $self = shift;
516 148273   50     501731 my $class = ref($self) || $self || __PACKAGE__;
517              
518             # setter/mutator
519              
520 148273 100       274362 if (@_) {
521 45877         70004 my $d = shift;
522 45877 50 33     111987 if (ref($self) && exists $self -> {downgrade}) {
523 0         0 $self -> {downgrade} = $d;
524             } else {
525 50     50   344 no strict 'refs';
  50         114  
  50         4419  
526 45877         62781 ${"${class}::downgrade"} = $d;
  45877         154121  
527             }
528             }
529              
530             # getter/accessor
531              
532             else {
533 102396 50 33     232790 if (ref($self) && exists $self -> {downgrade}) {
534 0         0 return $self -> {downgrade};
535             } else {
536 50     50   387 no strict 'refs';
  50         198  
  50         297779  
537 102396         143802 return ${"${class}::downgrade"};
  102396         374367  
538             }
539             }
540             }
541              
542             sub modify () {
543             # This method returns 0 if the object can be modified, or 1 if not. We use
544             # a fast constant sub() here, to avoid costly calls. Subclasses may
545             # override it with special code (f.i. Math::BigInt::Constant does so).
546              
547             0;
548             }
549              
550             sub config {
551             # return (or set) configuration data.
552 919     919 1 1733937 my $self = shift;
553 919   50     4380 my $class = ref($self) || $self || __PACKAGE__;
554              
555             # setter/mutator
556             #
557             # $self -> config(param => value, ...)
558             # $self -> config({ param => value, ... })
559              
560 919 100 100     5429 if (@_ > 1 || (@_ == 1 && (ref($_[0]) eq 'HASH'))) {
      100        
561             # try to set given options as arguments from hash
562              
563             # If the argument is a hash ref, make a copy of it, since hash keys
564             # will be deleted below, and we don't want to modify the input hash.
565              
566 166 100       715 my $args = ref($_[0]) eq 'HASH' ? { %{ $_[0] } }: { @_ };
  51         206  
567              
568             # We use this special handling of accuracy and precision because
569             # accuracy() always sets precision to undef and precision() always sets
570             # accuracy to undef. With out this special treatment, the following
571             # would result in both accuracy and precision being undef.
572             #
573             # $x -> config(accuracy => 3, precision => undef)
574              
575             croak "config(): both accuracy and precision are defined"
576 166 50 66     699 if defined($args -> {accuracy}) && defined ($args -> {precision});
577              
578 166 100       577 if (defined $args -> {accuracy}) {
    100          
579 18         93 $self -> accuracy($args -> {accuracy});
580             } elsif (defined $args -> {precision}) {
581 24         121 $self -> precision($args -> {precision});
582             } else {
583 124         392 $self -> accuracy(undef); # also sets precision to undef
584             }
585              
586 166         347 delete $args->{accuracy};
587 166         285 delete $args->{precision};
588              
589             # Set any remaining hash keys.
590              
591 166         396 foreach my $key (qw/
592             round_mode div_scale
593             upgrade downgrade
594             trap_inf trap_nan
595             /)
596             {
597             # use a method call to check argument
598 996 100       2101 $self -> $key($args->{$key}) if exists $args->{$key};
599 996         1418 delete $args->{$key};
600             }
601              
602             # If there are any keys left, they are invalid.
603              
604 166 100       568 if (keys %$args) {
605 6         1620 croak("Illegal key(s) '", join("', '", keys %$args),
606             "' passed to ${class}->config()");
607             }
608             }
609              
610             # getter/accessor
611              
612 913         2156 my $cfg = {};
613              
614             # When only a single parameter is wanted, it is not necessary to build the
615             # whole configuration first.
616              
617 913 100 100     3755 if (@_ == 1 && (ref($_[0]) ne 'HASH')) {
618 743         1499 my $param = shift;
619              
620 743 100       3037 return $LIB if $param eq 'lib';
621 454 100       943 return $LIB -> VERSION() if $param eq 'lib_version';
622 451 100       904 return $class if $param eq 'class';
623 450 100       858 return $class -> VERSION() if $param eq 'version';
624              
625             # $x -> config("param") or $class -> config("param")
626              
627 447         1367 return $self -> $param();
628             }
629              
630             else {
631              
632 170 100       434 if (ref($self)) { # $x -> config()
633              
634             # Currently, only 'accuracy' and 'precision' are supported, but
635             # more parameters will be added as the global variables are moved
636             # into the OO interface.
637              
638 36         198 my @param = ('accuracy', 'precision');
639              
640 36         117 for my $param (@param) {
641 72         277 $cfg -> {$param} = $self -> {$param};
642             }
643              
644             } else { # $class -> config()
645              
646 134         413 my @param = ('accuracy', 'precision', 'round_mode', 'div_scale',
647             'upgrade', 'downgrade', 'trap_inf', 'trap_nan');
648              
649 134         228 for my $param (@param) {
650 1072         2610 $cfg -> {$param} = $self -> $param();
651             }
652              
653             # Additional read-only parameters.
654              
655 134         264 $cfg -> {lib} = $LIB;
656 134         1479 $cfg -> {lib_version} = $LIB -> VERSION();
657 134         586 $cfg -> {class} = $class;
658 134         713 $cfg -> {version} = $class -> VERSION();
659             }
660              
661 170         683 return $cfg;
662             }
663             }
664              
665             sub _scale_a {
666             # select accuracy parameter based on precedence,
667             # used by bround() and bfround(), may return undef for scale (means no op)
668 77210     77210   170471 my ($x, $scale, $mode) = @_;
669              
670 77210 100       155671 $scale = $x->{accuracy} unless defined $scale;
671              
672 77210         131773 my $class = ref($x);
673              
674 77210 100       168044 $mode = $class -> round_mode() unless defined $mode;
675              
676 77210 100       155916 if (defined $scale) {
677 72639 50       143515 $scale = $scale -> can('numify') ? $scale -> numify()
    100          
678             : "$scale" if ref($scale);
679 72639         113506 $scale = int($scale);
680             }
681              
682 77210         250173 ($scale, $mode);
683             }
684              
685             sub _scale_p {
686             # select precision parameter based on precedence,
687             # used by bround() and bfround(), may return undef for scale (means no op)
688 975     975   2588 my ($x, $scale, $mode) = @_;
689              
690 975 100       2495 $scale = $x->{precision} unless defined $scale;
691              
692 975         1965 my $class = ref($x);
693              
694 975 100       2391 $scale = $class -> precision() unless defined $scale;
695 975 100       7759 $mode = $class -> round_mode() unless defined $mode;
696              
697 975 100       2679 if (defined $scale) {
698 971 0       2425 $scale = $scale -> can('numify') ? $scale -> numify()
    50          
699             : "$scale" if ref($scale);
700 971         1807 $scale = int($scale);
701             }
702              
703 975         4081 ($scale, $mode);
704             }
705              
706             # An undocumented method which downgrades an instance to its downgrade class.
707              
708             sub _dng {
709 59936     59936   92571 my $self = shift;
710 59936         102771 my $class = ref($self);
711              
712 59936         143802 my $downgrade = $class -> downgrade();
713 59936 100       161462 return $self unless $downgrade; # bail out if no downgrading
714 141 50       448 return $self if ref($self) eq $downgrade; # bail out if already downgraded
715              
716             # new() might perform upgrading or downgrading, so temporarily disable
717             # upgrading and downgrading in the downgrade class while calling new(). It
718             # should be possible to give new() extra arguments that disable
719             # downgrading. XXX
720              
721 141         462 my $upg = $downgrade -> upgrade();
722 141         372 my $dng = $downgrade -> downgrade();
723              
724 141         496 $downgrade -> upgrade(undef);
725 141         360 $downgrade -> downgrade(undef);
726              
727 141         368 my $tmp = $downgrade -> new($self); # new instance
728              
729 141         443 $downgrade -> upgrade($upg);
730 141         418 $downgrade -> downgrade($dng);
731              
732 141         298 for my $param ('accuracy', 'precision') { # copy instance variables
733 282 100       800 $tmp -> {$param} = $self -> {$param} if exists $self -> {$param};
734             }
735              
736 141         1015 %$self = %$tmp; # replace
737 141         352 bless $self, $downgrade; # bless into downgrade class
738              
739 141         652 return $self;
740             }
741              
742             # An undocumented method which upgrades an instance to its upgrade class.
743              
744             sub _upg {
745 74     74   126 my $self = shift;
746 74         205 my $class = ref($self);
747              
748 74         177 my $upgrade = $class -> upgrade();
749 74 50       239 return $self unless $upgrade; # bail out if no upgrading
750 74 50       165 return $self if ref($self) eq $upgrade; # bail out if already upgraded
751              
752             # new() might perform upgrading or downgrading, so temporarily disable
753             # upgrading and downgrading in the upgrade class while calling new(). It
754             # should be possible to give new() extra arguments that disable
755             # upgrading. XXX
756              
757 74         229 my $upg = $upgrade -> upgrade();
758 74         187 my $dng = $upgrade -> downgrade();
759              
760 74         175 $upgrade -> upgrade(undef);
761 74         158 $upgrade -> downgrade(undef);
762              
763 74         287 my $tmp = $upgrade -> new($self); # new instance
764              
765 74         271 $upgrade -> upgrade($upg);
766 74         171 $upgrade -> downgrade($dng);
767              
768 74         123 for my $param ('accuracy', 'precision') { # copy instance variables
769 148 100       346 $tmp -> {$param} = $self -> {$param} if exists $self -> {$param};
770             }
771              
772 74         560 %$self = %$tmp; # replace
773 74         190 bless $self, $upgrade; # bless into upgrade class
774              
775 74         478 return $self;
776             }
777              
778             ###############################################################################
779             # Constructor methods
780             ###############################################################################
781              
782             sub _init {
783 9     9   14 my $self = shift;
784 9         16 my $class = ref($self);
785              
786 9 50       65 $self -> SUPER::_init() if SUPER -> can('_init');
787              
788 9         23 $self -> {accuracy} = $class -> accuracy();
789 9         43 $self -> {precision} = $class -> precision();
790              
791             #$self -> {round_mode} = $round_mode;
792             #$self -> {div_scale} = $div_scale;
793              
794             #$self -> {trap_inf} = $_trap_inf;
795             #$self -> {trap_nan} = $_trap_nan;
796              
797             #$self -> {upgrade} = $upgrade;
798             #$self -> {downgrade} = $downgrade;
799              
800 9         21 return $self;
801             }
802              
803             sub new {
804             # Create a new Math::BigInt object from a string or another Math::BigInt,
805             # Math::BigFloat, or Math::BigRat object. See hash keys documented at top.
806              
807 22382     22382 1 9069241 my $self = shift;
808 22382         44491 my $selfref = ref $self;
809 22382   33     105636 my $class = $selfref || $self;
810              
811             # Make "require" work.
812              
813 22382 100       60105 $class -> import() if $IMPORT == 0;
814              
815             # Calling new() with no input arguments has been discouraged for more than
816             # 10 years, but people apparently still use it, so we still support it.
817              
818 22382 100       57092 return $class -> bzero() unless @_;
819              
820 22374         51431 my ($wanted, @r) = @_;
821              
822 22374 50       51500 if (!defined($wanted)) {
823             #carp("Use of uninitialized value in new()")
824             # if warnings::enabled("uninitialized");
825 0         0 return $class -> bzero(@r);
826             }
827              
828 22374 100 100     89259 if (!ref($wanted) && $wanted eq "") {
829             #carp(q|Argument "" isn't numeric in new()|)
830             # if warnings::enabled("numeric");
831             #return $class -> bzero(@r);
832 4         28 return $class -> bnan(@r);
833             }
834              
835             # Initialize a new object.
836              
837 22370         60388 $self = bless {}, $class;
838             #$self -> _init(); # <-- this causes problems because if the global
839             # accuracy is 2, new(3, 5) will not set the accuracy
840             # to 5 because it is currently not possible to
841             # increase the accuracy. Ditto for precision. XXX
842              
843             # See if $wanted is an object that is a Math::BigInt. We could check if the
844             # object supports the as_int() method. However, as_int() truncates a finite
845             # non-integer whereas new() is supposed to return a NaN for finite
846             # non-integers. This inconsistency should be sorted out. XXX
847              
848 22370 100 100     64644 if (defined(blessed($wanted)) && $wanted -> isa(__PACKAGE__)) {
849              
850             # Don't copy the accuracy and precision, because a new object should
851             # get them from the global configuration.
852              
853 1         3 $self -> {sign} = $wanted -> {sign};
854 1         5 $self -> {value} = $LIB -> _copy($wanted -> {value});
855 1 0 33     5 $self -> round(@r)
      33        
856             unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
857 1         3 return $self;
858             }
859              
860             # From now on we only work on the stringified version of $wanted, so
861             # stringify it once and for all.
862              
863 22369         45193 $wanted = "$wanted";
864              
865             # Shortcut for non-zero scalar integers with no non-zero exponent.
866              
867 22369 100       175084 if ($wanted =~
868             / ^
869              
870             # optional leading whitespace
871             \s*
872              
873             # optional sign
874             ( [+-]? )
875              
876             # integer mantissa with optional leading zeros
877             0* ( [1-9] \d* (?: _ \d+ )* | 0 )
878              
879             # ... with optional zero fraction part
880             (?: \.0* )?
881              
882             # optional non-negative exponent
883             (?: [eE] \+? ( \d+ (?: _ \d+ )* ) )?
884              
885             # optional trailing whitespace
886             \s*
887              
888             $
889             /x)
890             {
891 18009         47361 my $sign = $1;
892 18009         52690 (my $mant = $2) =~ tr/_//d;
893 18009         42319 my $expo = $3;
894 18009 100 100     54549 $mant .= "0" x $expo if defined($expo) && $mant ne "0";
895              
896 18009 100 100     93865 $self->{sign} = $sign eq "-" && $mant ne "0" ? "-" : "+";
897 18009         84045 $self->{value} = $LIB->_new($mant);
898 18009         66365 $self -> round(@r);
899 18009         205163 return $self;
900             }
901              
902             # Handle Infs.
903              
904 4360 100       25429 if ($wanted =~ / ^
905             \s*
906             ( [+-]? )
907             inf (?: inity )?
908             \s*
909             \z
910             /ix)
911             {
912 1838   100     8749 my $sgn = $1 || '+';
913 1838         8176 return $class -> binf($sgn, @r);
914             }
915              
916             # Handle explicit NaNs (not the ones returned due to invalid input).
917              
918 2522 100       11398 if ($wanted =~ / ^
919             \s*
920             ( [+-]? )
921             nan
922             \s*
923             \z
924             /ix)
925             {
926 494         2481 return $class -> bnan(@r);
927             }
928              
929 2028         3496 my @parts;
930              
931 2028 100 100     25747 if (
      33        
      66        
      100        
      66        
      100        
      33        
      66        
932             # Handle hexadecimal numbers. We auto-detect hexadecimal numbers if
933             # they have a "0x", "0X", "x", or "X" prefix, cf. CORE::oct().
934              
935             $wanted =~ /^\s*[+-]?0?[Xx]/ and
936             @parts = $class -> _hex_str_to_flt_lib_parts($wanted)
937              
938             or
939              
940             # Handle octal numbers. We auto-detect octal numbers if they have a
941             # "0o", "0O", "o", "O" prefix, cf. CORE::oct().
942              
943             $wanted =~ /^\s*[+-]?0?[Oo]/ and
944             @parts = $class -> _oct_str_to_flt_lib_parts($wanted)
945              
946             or
947              
948             # Handle binary numbers. We auto-detect binary numbers if they have a
949             # "0b", "0B", "b", or "B" prefix, cf. CORE::oct().
950              
951             $wanted =~ /^\s*[+-]?0?[Bb]/ and
952             @parts = $class -> _bin_str_to_flt_lib_parts($wanted)
953              
954             or
955              
956             # At this point, what is left are decimal numbers that aren't handled
957             # above and octal floating point numbers that don't have any of the
958             # "0o", "0O", "o", or "O" prefixes. First see if it is a decimal
959             # number.
960              
961             @parts = $class -> _dec_str_to_flt_lib_parts($wanted)
962             or
963              
964             # See if it is an octal floating point number. The extra check is
965             # included because _oct_str_to_flt_lib_parts() accepts octal numbers
966             # that don't have a prefix (this is needed to make it work with, e.g.,
967             # from_oct() that don't require a prefix). However, Perl requires a
968             # prefix for octal floating point literals. For example, "1p+0" is not
969             # valid, but "01p+0" and "0__1p+0" are.
970              
971             $wanted =~ /^\s*[+-]?0_*\d/ and
972             @parts = $class -> _oct_str_to_flt_lib_parts($wanted))
973             {
974             # The value is an integer iff the exponent is non-negative.
975              
976 1385 100       4033 if ($parts[2] eq '+') {
977 1340         4826 $self -> {sign} = $parts[0];
978 1340         6242 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
979 1340 0 33     7473 $self -> round(@r)
      33        
980             unless @r >= 2 && !defined($r[0]) && !defined($r[1]);
981 1340         20413 return $self;
982             }
983              
984             # The value is not an integer, so upgrade if upgrading is enabled.
985              
986 45         269 my $upg = $class -> upgrade();
987 45 100       251 return $upg -> new($wanted, @r) if $upg;
988             }
989              
990             # If we get here, the value is neither a valid decimal, binary, octal, or
991             # hexadecimal number. It is not explicit an Inf or a NaN either.
992              
993 678         2767 return $class -> bnan(@r);
994             }
995              
996             # Create a Math::BigInt from a decimal string. This is an equivalent to
997             # from_hex(), from_oct(), and from_bin(). It is like new() except that it does
998             # not accept anything but a string representing a finite decimal number.
999              
1000             sub from_dec {
1001 0     0 1 0 my $self = shift;
1002 0         0 my $selfref = ref $self;
1003 0   0     0 my $class = $selfref || $self;
1004              
1005             # Make "require" work.
1006              
1007 0 0       0 $class -> import() if $IMPORT == 0;
1008              
1009             # Don't modify constant (read-only) objects.
1010              
1011 0 0 0     0 return $self if $selfref && $self -> modify('from_dec');
1012              
1013 0         0 my $str = shift;
1014 0         0 my @r = @_;
1015              
1016 0 0       0 if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
1017              
1018             # If called as a class method, initialize a new object.
1019              
1020 0 0       0 unless ($selfref) {
1021 0         0 $self = bless {}, $class;
1022             #$self -> _init(); # see comment on _init() in new()
1023             }
1024              
1025             # The value is an integer iff the exponent is non-negative.
1026              
1027 0 0       0 if ($parts[2] eq '+') {
1028 0         0 $self -> {sign} = $parts[0];
1029 0         0 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
1030 0         0 return $self -> round(@r);
1031             }
1032              
1033             # The value is not an integer, so upgrade if upgrading is enabled.
1034              
1035 0         0 my $upg = $class -> upgrade();
1036 0 0       0 if ($upg) {
1037 0 0 0     0 return $self -> _upg() -> from_dec($str, @r) # instance method
1038             if $selfref && $selfref ne $upg;
1039 0         0 return $upg -> from_dec($str, @r); # class method
1040             }
1041             }
1042              
1043 0         0 return $self -> bnan(@r);
1044             }
1045              
1046             # Create a Math::BigInt from a hexadecimal string.
1047              
1048             sub from_hex {
1049 2     2 1 1630 my $self = shift;
1050 2         33 my $selfref = ref $self;
1051 2   33     12 my $class = $selfref || $self;
1052              
1053             # Make "require" work.
1054              
1055 2 50       7 $class -> import() if $IMPORT == 0;
1056              
1057             # Don't modify constant (read-only) objects.
1058              
1059 2 50 33     9 return $self if $selfref && $self -> modify('from_hex');
1060              
1061 2         4 my $str = shift;
1062 2         6 my @r = @_;
1063              
1064 2 50       11 if (my @parts = $class -> _hex_str_to_flt_lib_parts($str)) {
1065              
1066             # If called as a class method, initialize a new object.
1067              
1068 2 50       7 unless ($selfref) {
1069 2         7 $self = bless {}, $class;
1070             #$self -> _init(); # see comment on _init() in new()
1071             }
1072              
1073             # The value is an integer iff the exponent is non-negative.
1074              
1075 2 50       7 if ($parts[2] eq '+') {
1076 2         8 $self -> {sign} = $parts[0];
1077 2         12 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
1078 2         8 return $self -> round(@r);
1079             }
1080              
1081             # The value is not an integer, so upgrade if upgrading is enabled.
1082              
1083 0         0 my $upg = $class -> upgrade();
1084 0 0       0 if ($upg) {
1085 0 0 0     0 return $self -> _upg() -> from_hex($str, @r) # instance method
1086             if $selfref && $selfref ne $upg;
1087 0         0 return $upg -> from_hex($str, @r); # class method
1088             }
1089             }
1090              
1091 0         0 return $self -> bnan(@r);
1092             }
1093              
1094             # Create a Math::BigInt from an octal string.
1095              
1096             sub from_oct {
1097 2     2 1 1698 my $self = shift;
1098 2         6 my $selfref = ref $self;
1099 2   33     13 my $class = $selfref || $self;
1100              
1101             # Make "require" work.
1102              
1103 2 50       8 $class -> import() if $IMPORT == 0;
1104              
1105             # Don't modify constant (read-only) objects.
1106              
1107 2 50 33     8 return $self if $selfref && $self -> modify('from_oct');
1108              
1109 2         3 my $str = shift;
1110 2         5 my @r = @_;
1111              
1112 2 50       11 if (my @parts = $class -> _oct_str_to_flt_lib_parts($str)) {
1113              
1114             # If called as a class method, initialize a new object.
1115              
1116 2 50       7 unless ($selfref) {
1117 2         7 $self = bless {}, $class;
1118             #$self -> _init(); # see comment on _init() in new()
1119             }
1120              
1121             # The value is an integer iff the exponent is non-negative.
1122              
1123 2 50       6 if ($parts[2] eq '+') {
1124 2         8 $self -> {sign} = $parts[0];
1125 2         9 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
1126 2         8 return $self -> round(@r);
1127             }
1128              
1129             # The value is not an integer, so upgrade if upgrading is enabled.
1130              
1131 0         0 my $upg = $class -> upgrade();
1132 0 0       0 if ($upg) {
1133 0 0 0     0 return $self -> _upg() -> from_oct($str, @r) # instance method
1134             if $selfref && $selfref ne $upg;
1135 0         0 return $upg -> from_oct($str, @r); # class method
1136             }
1137             }
1138              
1139 0         0 return $self -> bnan(@r);
1140             }
1141              
1142             # Create a Math::BigInt from a binary string.
1143              
1144             sub from_bin {
1145 53     53 1 1805 my $self = shift;
1146 53         97 my $selfref = ref $self;
1147 53   33     187 my $class = $selfref || $self;
1148              
1149             # Make "require" work.
1150              
1151 53 50       140 $class -> import() if $IMPORT == 0;
1152              
1153             # Don't modify constant (read-only) objects.
1154              
1155 53 50 33     146 return $self if $selfref && $self -> modify('from_bin');
1156              
1157 53         90 my $str = shift;
1158 53         113 my @r = @_;
1159              
1160 53 50       190 if (my @parts = $class -> _bin_str_to_flt_lib_parts($str)) {
1161              
1162             # If called as a class method, initialize a new object.
1163              
1164 53 50       143 unless ($selfref) {
1165 53         156 $self = bless {}, $class;
1166             #$self -> _init(); # see comment on _init() in new()
1167             }
1168              
1169             # The value is an integer iff the exponent is non-negative.
1170              
1171 53 50       180 if ($parts[2] eq '+') {
1172 53         339 $self -> {sign} = $parts[0];
1173 53         244 $self -> {value} = $LIB -> _lsft($parts[1], $parts[3], 10);
1174 53         219 return $self -> round(@r);
1175             }
1176              
1177             # The value is not an integer, so upgrade if upgrading is enabled.
1178              
1179 0         0 my $upg = $class -> upgrade();
1180 0 0       0 if ($upg) {
1181 0 0 0     0 return $self -> _upg() -> from_bin($str, @r) # instance method
1182             if $selfref && $selfref ne $upg;
1183 0         0 return $upg -> from_bin($str, @r); # class method
1184             }
1185             }
1186              
1187 0         0 return $self -> bnan(@r);
1188             }
1189              
1190             # Create a Math::BigInt from a byte string.
1191              
1192             sub from_bytes {
1193 0     0 1 0 my $self = shift;
1194 0         0 my $selfref = ref $self;
1195 0   0     0 my $class = $selfref || $self;
1196              
1197             # Make "require" work.
1198              
1199 0 0       0 $class -> import() if $IMPORT == 0;
1200              
1201             # Don't modify constant (read-only) objects.
1202              
1203 0 0 0     0 return $self if $selfref && $self -> modify('from_bytes');
1204              
1205 0 0       0 croak("from_bytes() requires a newer version of the $LIB library.")
1206             unless $LIB -> can('_from_bytes');
1207              
1208 0         0 my $str = shift;
1209 0         0 my @r = @_;
1210              
1211             # If called as a class method, initialize a new object.
1212              
1213 0 0       0 $self = $class -> bzero(@r) unless $selfref;
1214 0         0 $self -> {sign} = '+';
1215 0         0 $self -> {value} = $LIB -> _from_bytes($str);
1216 0         0 return $self -> round(@r);
1217             }
1218              
1219             sub from_ieee754 {
1220 0     0 1 0 my $self = shift;
1221 0         0 my $selfref = ref $self;
1222 0   0     0 my $class = $selfref || $self;
1223              
1224             # Make "require" work.
1225              
1226 0 0       0 $class -> import() if $IMPORT == 0;
1227              
1228             # Don't modify constant (read-only) objects.
1229              
1230 0 0 0     0 return $self if $selfref && $self -> modify('from_ieee754');
1231              
1232 0         0 my $in = shift;
1233 0         0 my $format = shift;
1234 0         0 my @r = @_;
1235              
1236 0         0 require Math::BigFloat;
1237 0         0 my $tmp = Math::BigFloat -> from_ieee754($in, $format, @r);
1238 0 0 0     0 return $self -> bnan(@r) unless $tmp -> is_inf() || $tmp -> is_int();
1239 0         0 $tmp = $tmp -> as_int();
1240              
1241             # If called as a class method, initialize a new object.
1242              
1243 0 0       0 $self = $class -> bzero(@r) unless $selfref;
1244 0         0 $self -> {sign} = $tmp -> {sign};
1245 0         0 $self -> {value} = $tmp -> {value};
1246              
1247 0         0 return $self;
1248             }
1249              
1250             sub from_fp80 {
1251 0     0 1 0 my $self = shift;
1252 0         0 my $selfref = ref $self;
1253 0   0     0 my $class = $selfref || $self;
1254              
1255             # Make "require" work.
1256              
1257 0 0       0 $class -> import() if $IMPORT == 0;
1258              
1259             # Don't modify constant (read-only) objects.
1260              
1261 0 0 0     0 return $self if $selfref && $self -> modify('from_fp80');
1262              
1263 0         0 my $in = shift;
1264 0         0 my @r = @_;
1265              
1266 0         0 require Math::BigFloat;
1267 0         0 my $tmp = Math::BigFloat -> from_fp80($in, @r);
1268 0 0 0     0 return $self -> bnan(@r) unless $tmp -> is_inf() || $tmp -> is_int();
1269 0         0 $tmp = $tmp -> as_int();
1270              
1271             # If called as a class method, initialize a new object.
1272              
1273 0 0       0 $self = $class -> bzero(@r) unless $selfref;
1274 0         0 $self -> {sign} = $tmp -> {sign};
1275 0         0 $self -> {value} = $tmp -> {value};
1276              
1277 0         0 return $self;
1278             }
1279              
1280             sub from_base {
1281 0     0 1 0 my $self = shift;
1282 0         0 my $selfref = ref $self;
1283 0   0     0 my $class = $selfref || $self;
1284              
1285             # Make "require" work.
1286              
1287 0 0       0 $class -> import() if $IMPORT == 0;
1288              
1289             # Don't modify constant (read-only) objects.
1290              
1291 0 0 0     0 return $self if $selfref && $self -> modify('from_base');
1292              
1293 0         0 my ($str, $base, $cs, @r) = @_; # $cs is the collation sequence
1294              
1295 0 0       0 $base = $class -> new($base) unless ref($base);
1296              
1297 0 0 0     0 croak("the base must be a finite integer >= 2")
1298             if $base < 2 || ! $base -> is_int();
1299              
1300             # If called as a class method, initialize a new object.
1301              
1302 0 0       0 $self = $class -> bzero() unless $selfref;
1303              
1304             # If no collating sequence is given, pass some of the conversions to
1305             # methods optimized for those cases.
1306              
1307 0 0       0 unless (defined $cs) {
1308 0 0       0 return $self -> from_bin($str, @r) if $base == 2;
1309 0 0       0 return $self -> from_oct($str, @r) if $base == 8;
1310 0 0       0 return $self -> from_hex($str, @r) if $base == 16;
1311 0 0       0 return $self -> from_dec($str, @r) if $base == 10;
1312             }
1313              
1314 0 0       0 croak("from_base() requires a newer version of the $LIB library.")
1315             unless $LIB -> can('_from_base');
1316              
1317 0         0 $self -> {sign} = '+';
1318             $self -> {value} = $LIB->_from_base($str, $base -> {value},
1319 0 0       0 defined($cs) ? $cs : ());
1320 0         0 return $self -> bround(@r);
1321             }
1322              
1323             sub from_base_num {
1324 0     0 1 0 my $self = shift;
1325 0         0 my $selfref = ref $self;
1326 0   0     0 my $class = $selfref || $self;
1327              
1328             # Make "require" work.
1329              
1330 0 0       0 $class -> import() if $IMPORT == 0;
1331              
1332             # Don't modify constant (read-only) objects.
1333              
1334 0 0 0     0 return $self if $selfref && $self -> modify('from_base_num');
1335              
1336             # Make sure we have an array of non-negative, finite, numerical objects.
1337              
1338 0         0 my $nums = shift;
1339 0         0 $nums = [ @$nums ]; # create new reference
1340              
1341 0         0 for my $i (0 .. $#$nums) {
1342             # Make sure we have an object.
1343 0 0 0     0 $nums -> [$i] = $class -> new($nums -> [$i])
1344             unless defined(blessed($nums -> [$i]))
1345             && $nums -> [$i] -> isa(__PACKAGE__);
1346             # Make sure we have a finite, non-negative integer.
1347 0 0 0     0 croak "the elements must be finite non-negative integers"
1348             if $nums -> [$i] -> is_neg() || ! $nums -> [$i] -> is_int();
1349             }
1350              
1351 0         0 my $base = shift;
1352 0 0 0     0 $base = $class -> new($base)
1353             unless defined(blessed($base)) && $base -> isa(__PACKAGE__);
1354              
1355 0         0 my @r = @_;
1356              
1357             # If called as a class method, initialize a new object.
1358              
1359 0 0       0 $self = $class -> bzero(@r) unless $selfref;
1360              
1361 0 0       0 croak("from_base_num() requires a newer version of the $LIB library.")
1362             unless $LIB -> can('_from_base_num');
1363              
1364 0         0 $self -> {sign} = '+';
1365 0         0 $self -> {value} = $LIB -> _from_base_num([ map { $_ -> {value} } @$nums ],
1366 0         0 $base -> {value});
1367              
1368 0         0 return $self -> round(@r);
1369             }
1370              
1371             sub bzero {
1372             # create/assign '+0'
1373              
1374             # Class::method(...) -> Class->method(...)
1375 1917 50 66 1917 1 36510 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1376             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1377             {
1378             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1379             # " use is as a method instead";
1380 0         0 unshift @_, __PACKAGE__;
1381             }
1382              
1383 1917         4245 my $self = shift;
1384 1917         4048 my $selfref = ref $self;
1385 1917   66     6611 my $class = $selfref || $self;
1386              
1387             # Make "require" work.
1388              
1389 1917 50       5090 $class -> import() if $IMPORT == 0;
1390              
1391             # Don't modify constant (read-only) objects.
1392              
1393 1917 50 66     6690 return $self if $selfref && $self -> modify('bzero');
1394              
1395             # Get the rounding parameters, if any.
1396              
1397 1917         4164 my @r = @_;
1398              
1399             # If called as a class method, initialize a new object.
1400              
1401 1917 100       4809 unless ($selfref) {
1402 1474         3894 $self = bless {}, $class;
1403             #$self -> _init(); # see comment on _init() in new()
1404             }
1405              
1406 1917         5654 $self->{sign} = '+';
1407 1917         8550 $self->{value} = $LIB->_zero();
1408              
1409             # If rounding parameters are given as arguments, use them. If no rounding
1410             # parameters are given, and if called as a class method, initialize the new
1411             # instance with the class variables.
1412              
1413 1917 100       7049 if (@r) {
    100          
1414 18 50 100     133 if (@r >= 2 && defined($r[0]) && defined($r[1])) {
      66        
1415 0         0 carp "can't specify both accuracy and precision";
1416 0         0 return $self -> bnan();
1417             }
1418 18         59 $self->{accuracy} = $_[0];
1419 18         48 $self->{precision} = $_[1];
1420             } elsif (!$selfref) {
1421 1468         4131 $self->{accuracy} = $class -> accuracy();
1422 1468         4114 $self->{precision} = $class -> precision();
1423             }
1424              
1425 1917         7345 return $self;
1426             }
1427              
1428             sub bone {
1429             # Create or assign '+1' (or -1 if given sign '-').
1430              
1431             # Class::method(...) -> Class->method(...)
1432 499 50 66 499 1 35864 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1433             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1434             {
1435             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1436             # " use is as a method instead";
1437 0         0 unshift @_, __PACKAGE__;
1438             }
1439              
1440 499         1268 my $self = shift;
1441 499         1073 my $selfref = ref $self;
1442 499   66     2079 my $class = $selfref || $self;
1443              
1444             # Make "require" work.
1445              
1446 499 50       1520 $class -> import() if $IMPORT == 0;
1447              
1448             # Don't modify constant (read-only) objects.
1449              
1450 499 50 66     2464 return $self if $selfref && $self -> modify('bone');
1451              
1452 499         1337 my ($sign, @r) = @_;
1453              
1454             # Get the sign.
1455              
1456 499 100 100     2371 if (defined($_[0]) && $_[0] =~ /^\s*([+-])\s*$/) {
1457 104         317 $sign = $1;
1458 104         217 shift;
1459             } else {
1460 395         958 $sign = '+';
1461             }
1462              
1463             # If called as a class method, initialize a new object.
1464              
1465 499 100       1313 unless ($selfref) {
1466 287         952 $self = bless {}, $class;
1467             #$self -> _init(); # see comment on _init() in new()
1468             }
1469              
1470 499         1710 $self->{sign} = $sign;
1471 499         2617 $self->{value} = $LIB->_one();
1472              
1473             # If rounding parameters are given as arguments, use them. If no rounding
1474             # parameters are given, and if called as a class method, initialize the new
1475             # instance with the class variables.
1476              
1477 499 100       2028 if (@r) {
    100          
1478 18 50 100     111 if (@r >= 2 && defined($r[0]) && defined($r[1])) {
      66        
1479 0         0 carp "can't specify both accuracy and precision";
1480 0         0 return $self -> bnan();
1481             }
1482 18         66 $self->{accuracy} = $_[0];
1483 18         43 $self->{precision} = $_[1];
1484             } elsif (!$selfref) {
1485 281         1051 $self->{accuracy} = $class -> accuracy();
1486 281         955 $self->{precision} = $class -> precision();
1487             }
1488              
1489 499         3410 return $self;
1490             }
1491              
1492             sub binf {
1493             # create/assign a '+inf' or '-inf'
1494              
1495             # Class::method(...) -> Class->method(...)
1496 2353 50 66 2353 1 29387 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1497             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1498             {
1499             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1500             # " use is as a method instead";
1501 0         0 unshift @_, __PACKAGE__;
1502             }
1503              
1504 2353         5186 my $self = shift;
1505 2353         5169 my $selfref = ref $self;
1506 2353   66     8386 my $class = $selfref || $self;
1507              
1508             {
1509 50     50   580 no strict 'refs';
  50         117  
  50         32138  
  2353         4050  
1510 2353 100       3698 if (${"${class}::_trap_inf"}) {
  2353         14488  
1511 5         816 croak("Tried to create +-inf in $class->binf()");
1512             }
1513             }
1514              
1515             # Make "require" work.
1516              
1517 2348 50       5822 $class -> import() if $IMPORT == 0;
1518              
1519             # Don't modify constant (read-only) objects.
1520              
1521 2348 50 66     21229 return $self if $selfref && $self -> modify('binf');
1522              
1523             # Get the sign.
1524              
1525 2348         4874 my $sign = '+'; # default is to return positive infinity
1526 2348 100 66     14421 if (defined($_[0]) && $_[0] =~ /^\s*([+-])(inf|$)/i) {
1527 2289         5240 $sign = $1;
1528 2289         3850 shift;
1529             }
1530              
1531             # Get the rounding parameters, if any.
1532              
1533 2348         5309 my @r = @_;
1534              
1535             # If called as a class method, initialize a new object.
1536              
1537 2348 100       5534 unless ($selfref) {
1538 1913         4681 $self = bless {}, $class;
1539             #$self -> _init(); # see comment on _init() in new()
1540             }
1541              
1542 2348         8553 $self -> {sign} = $sign . 'inf';
1543 2348         11633 $self -> {value} = $LIB -> _zero();
1544              
1545             # If rounding parameters are given as arguments, use them. If no rounding
1546             # parameters are given, and if called as a class method, initialize the new
1547             # instance with the class variables.
1548              
1549 2348 100       8813 if (@r) {
    100          
1550 143 50 33     919 if (@r >= 2 && defined($r[0]) && defined($r[1])) {
      33        
1551 0         0 carp "can't specify both accuracy and precision";
1552 0         0 return $self -> bnan();
1553             }
1554 143         433 $self->{accuracy} = $_[0];
1555 143         352 $self->{precision} = $_[1];
1556             } elsif (!$selfref) {
1557 1897         6363 $self->{accuracy} = $class -> accuracy();
1558 1897         5821 $self->{precision} = $class -> precision();
1559             }
1560              
1561 2348         32274 return $self;
1562             }
1563              
1564             sub bnan {
1565             # create/assign a 'NaN'
1566              
1567             # Class::method(...) -> Class->method(...)
1568 2454 50 66 2454 1 242214 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
1569             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1570             {
1571             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1572             # " use is as a method instead";
1573 0         0 unshift @_, __PACKAGE__;
1574             }
1575              
1576 2454         5092 my $self = shift;
1577 2454         4861 my $selfref = ref($self);
1578 2454   66     8558 my $class = $selfref || $self;
1579              
1580             {
1581 50     50   402 no strict 'refs';
  50         100  
  50         1656228  
  2454         3962  
1582 2454 100       3929 if (${"${class}::_trap_nan"}) {
  2454         12604  
1583 5         1016 croak("Tried to create NaN in $class->bnan()");
1584             }
1585             }
1586              
1587             # Make "require" work.
1588              
1589 2449 50       5936 $class -> import() if $IMPORT == 0;
1590              
1591             # Don't modify constant (read-only) objects.
1592              
1593 2449 50 66     9266 return $self if $selfref && $self -> modify('bnan');
1594              
1595             # Get the rounding parameters, if any.
1596              
1597 2449         9656 my @r = @_;
1598              
1599             # If called as a class method, initialize a new object.
1600              
1601 2449 100       5850 unless ($selfref) {
1602 1350         3786 $self = bless {}, $class;
1603             #$self -> _init(); # see comment on _init() in new()
1604             }
1605              
1606 2449         8401 $self -> {sign} = $nan;
1607 2449         10852 $self -> {value} = $LIB -> _zero();
1608              
1609             # If rounding parameters are given as arguments, use them. If no rounding
1610             # parameters are given, and if called as a class method, initialize the new
1611             # instance with the class variables.
1612              
1613 2449 100       10623 if (@r) {
    100          
1614 227 50 66     1416 if (@r >= 2 && defined($r[0]) && defined($r[1])) {
      33        
1615 0         0 carp "can't specify both accuracy and precision";
1616 0         0 return $self -> bnan();
1617             }
1618 227         556 $self->{accuracy} = $_[0];
1619 227         524 $self->{precision} = $_[1];
1620             } elsif (!$selfref) {
1621 1348         4355 $self->{accuracy} = $class -> accuracy();
1622 1348         3921 $self->{precision} = $class -> precision();
1623             }
1624              
1625 2449         28621 return $self;
1626             }
1627              
1628             sub bpi {
1629              
1630             # Class::method(...) -> Class->method(...)
1631 9 50 33 9 1 283 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      33        
1632             $_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i))
1633             {
1634             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
1635             # " use is as a method instead";
1636 0         0 unshift @_, __PACKAGE__;
1637             }
1638              
1639             # Called as Argument list
1640             # --------- -------------
1641             # Math::BigFloat->bpi() ("Math::BigFloat")
1642             # Math::BigFloat->bpi(10) ("Math::BigFloat", 10)
1643             # $x->bpi() ($x)
1644             # $x->bpi(10) ($x, 10)
1645             # Math::BigFloat::bpi() ()
1646             # Math::BigFloat::bpi(10) (10)
1647             #
1648             # In ambiguous cases, we favour the OO-style, so the following case
1649             #
1650             # $n = Math::BigFloat->new("10");
1651             # $x = Math::BigFloat->bpi($n);
1652             #
1653             # which gives an argument list with the single element $n, is resolved as
1654             #
1655             # $n->bpi();
1656              
1657 9         20 my $self = shift;
1658 9         18 my $selfref = ref $self;
1659 9   33     35 my $class = $selfref || $self;
1660 9         23 my @r = @_; # rounding paramters
1661              
1662             # Make "require" work.
1663              
1664 9 50       25 $class -> import() if $IMPORT == 0;
1665              
1666 9 50       21 if ($selfref) { # bpi() called as an instance method
1667 0 0       0 return $self if $self -> modify('bpi');
1668             } else { # bpi() called as a class method
1669 9         26 $self = bless {}, $class; # initialize new instance
1670             #$self -> _init(); # see comment on _init() in new()
1671             }
1672              
1673 9         63 my $upg = $class -> upgrade();
1674 9 50       29 if ($upg) {
1675 0 0 0     0 return $self -> _upg() -> bpi(@r) # instance method
1676             if $selfref && $selfref ne $upg;
1677 0         0 return $upg -> bpi(@r); # class method
1678             }
1679              
1680             # hard-wired to "3"
1681 9         25 $self -> {sign} = '+';
1682 9         38 $self -> {value} = $LIB -> _new("3");
1683 9         28 $self -> round(@r);
1684 9         132 return $self;
1685             }
1686              
1687             sub copy {
1688 4209     4209 1 28554 my ($x, $class);
1689 4209 50       9689 if (ref($_[0])) { # $y = $x -> copy()
1690 4209         7869 $x = shift;
1691 4209         8405 $class = ref($x);
1692             } else { # $y = Math::BigInt -> copy($x)
1693 0         0 $class = shift;
1694 0         0 $x = shift;
1695             }
1696              
1697 4209 50       10371 carp "Rounding is not supported for ", (caller(0))[3], "()" if @_;
1698              
1699 4209         10830 my $copy = bless {}, $class;
1700              
1701 4209         13355 $copy->{sign} = $x->{sign};
1702 4209         17316 $copy->{value} = $LIB->_copy($x->{value});
1703 4209 100       19800 $copy->{accuracy} = $x->{accuracy} if exists $x->{accuracy};
1704 4209 100       10211 $copy->{precision} = $x->{precision} if exists $x->{precision};
1705              
1706 4209         15951 return $copy;
1707             }
1708              
1709             sub as_int {
1710 5 50   5 1 25 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1711              
1712             # Temporarily disable upgrading and downgrading.
1713              
1714 5         23 my $upg = Math::BigInt -> upgrade();
1715 5         20 my $dng = Math::BigInt -> downgrade();
1716 5         17 Math::BigInt -> upgrade(undef);
1717 5         13 Math::BigInt -> downgrade(undef);
1718              
1719 5         9 my $y;
1720 5 50       36 if ($x -> isa("Math::BigInt")) {
1721 5         20 $y = $x -> copy();
1722             } else {
1723 0 0       0 if ($x -> is_inf()) {
    0          
1724 0         0 $y = Math::BigInt -> binf($x -> sign());
1725             } elsif ($x -> is_nan()) {
1726 0         0 $y = Math::BigInt -> bnan();
1727             } else {
1728 0         0 $y = Math::BigInt -> new($x -> copy() -> bint() -> bdstr());
1729             }
1730              
1731             # Copy the remaining instance variables.
1732              
1733 0         0 ($y->{accuracy}, $y->{precision}) = ($x->{accuracy}, $x->{precision});
1734             }
1735              
1736 5         23 $y -> round(@r);
1737              
1738             # Restore upgrading and downgrading.
1739              
1740 5         18 Math::BigInt -> upgrade($upg);
1741 5         12 Math::BigInt -> downgrade($dng);
1742              
1743 5         26 return $y;
1744             }
1745              
1746             sub as_rat {
1747 889 50   889 1 2545 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1748              
1749             # Temporarily disable upgrading and downgrading.
1750              
1751 889         5964 require Math::BigRat;
1752 889         2427 my $upg = Math::BigRat -> upgrade();
1753 889         2135 my $dng = Math::BigRat -> downgrade();
1754 889         2328 Math::BigRat -> upgrade(undef);
1755 889         2009 Math::BigRat -> downgrade(undef);
1756              
1757 889         1296 my $y;
1758 889 50       4296 if ($x -> isa("Math::BigRat")) {
1759 0         0 $y = $x -> copy();
1760             } else {
1761              
1762 889 50       2221 if ($x -> is_inf()) {
    50          
1763 0         0 $y = Math::BigRat -> binf($x -> sign());
1764             } elsif ($x -> is_nan()) {
1765 0         0 $y = Math::BigRat -> bnan();
1766             } else {
1767 889         2511 $y = Math::BigRat -> new($x -> bfstr());
1768             }
1769              
1770             # Copy the remaining instance variables.
1771              
1772 889         3277 ($y->{accuracy}, $y->{precision}) = ($x->{accuracy}, $x->{precision});
1773             }
1774              
1775 889         2697 $y -> round(@r);
1776              
1777             # Restore upgrading and downgrading.
1778              
1779 889         2249 Math::BigRat -> upgrade($upg);
1780 889         1897 Math::BigRat -> downgrade($dng);
1781              
1782 889         2141 return $y;
1783             }
1784              
1785             sub as_float {
1786 470 50   470 1 1815 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
1787              
1788             # Temporarily disable upgrading and downgrading.
1789              
1790 470         3505 require Math::BigFloat;
1791 470         1338 my $upg = Math::BigFloat -> upgrade();
1792 470         1346 my $dng = Math::BigFloat -> downgrade();
1793 470         1328 Math::BigFloat -> upgrade(undef);
1794 470         1393 Math::BigFloat -> downgrade(undef);
1795              
1796 470         779 my $y;
1797 470 50       2376 if ($x -> isa("Math::BigFloat")) {
1798 0         0 $y = $x -> copy();
1799             } else {
1800 470 100       1351 if ($x -> is_inf()) {
    50          
1801 4         30 $y = Math::BigFloat -> binf($x -> sign());
1802             } elsif ($x -> is_nan()) {
1803 0         0 $y = Math::BigFloat -> bnan();
1804             } else {
1805 466 50       1900 if ($x -> isa("Math::BigRat")) {
1806 0 0       0 if ($x -> is_int()) {
1807 0         0 $y = Math::BigFloat -> new($x -> bdstr());
1808             } else {
1809 0         0 my ($num, $den) = $x -> fparts();
1810 0         0 my $str = $num -> as_float() -> bdiv($den, @r) -> bdstr();
1811 0         0 $y = Math::BigFloat -> new($str);
1812             }
1813             } else {
1814 466         1928 $y = Math::BigFloat -> new($x -> bdstr());
1815             }
1816             }
1817              
1818             # Copy the remaining instance variables.
1819              
1820 470         2522 ($y->{accuracy}, $y->{precision}) = ($x->{accuracy}, $x->{precision});
1821             }
1822              
1823 470         1353 $y -> round(@r);
1824              
1825             # Restore upgrading and downgrading..
1826              
1827 470         1538 Math::BigFloat -> upgrade($upg);
1828 470         1255 Math::BigFloat -> downgrade($dng);
1829              
1830 470         1416 return $y;
1831             }
1832              
1833             ###############################################################################
1834             # Boolean methods
1835             ###############################################################################
1836              
1837             sub is_zero {
1838             # return true if arg (BINT or num_str) is zero (array '+', '0')
1839 36056 100   36056 1 266005 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1840              
1841 36056 100       104671 return 0 if $x->{sign} ne '+';
1842 32534 100       104572 return 1 if $LIB->_is_zero($x->{value});
1843 32031         132382 return 0;
1844             }
1845              
1846             sub is_one {
1847             # return true if arg (BINT or num_str) is +1, or -1 if sign is given
1848 2426 100   2426 1 10729 my (undef, $x, $sign) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1849              
1850 2426 100       4947 if (defined($sign)) {
1851 1832 50 66     6575 croak 'is_one(): sign argument must be "+" or "-"'
1852             unless $sign eq '+' || $sign eq '-';
1853             } else {
1854 594         1074 $sign = '+';
1855             }
1856              
1857 2426 100       7911 return 0 if $x->{sign} ne $sign;
1858 1469 100       6304 $LIB->_is_one($x->{value}) ? 1 : 0;
1859             }
1860              
1861             sub is_finite {
1862 262811 50   262811 1 586594 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1863 262811 100 100     1118082 $x->{sign} eq '+' || $x->{sign} eq '-' ? 1 : 0;
1864             }
1865              
1866             sub is_inf {
1867             # return true if arg (BINT or num_str) is +-inf
1868 121294 100   121294 1 328286 my (undef, $x, $sign) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1869              
1870 121294 100       280192 if (defined $sign) {
1871 44340 100       92328 $sign = '[+-]inf' if $sign eq ''; # +- doesn't matter, only that's inf
1872 44340 100       235542 $sign = "[$1]inf" if $sign =~ /^([+-])(inf)?$/; # extract '+' or '-'
1873 44340 100       685894 return $x->{sign} =~ /^$sign$/ ? 1 : 0;
1874             }
1875 76954 100       383680 $x->{sign} =~ /^[+-]inf$/ ? 1 : 0; # only +-inf is infinity
1876             }
1877              
1878             sub is_nan {
1879             # return true if arg (BINT or num_str) is NaN
1880 152634 100   152634 1 340016 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1881              
1882 152634 100       600340 $x->{sign} eq $nan ? 1 : 0;
1883             }
1884              
1885             sub is_positive {
1886             # return true when arg (BINT or num_str) is positive (> 0)
1887 828 100   828 1 9758 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1888              
1889 828 100       2281 return 1 if $x -> is_inf("+");
1890              
1891             # 0+ is neither positive nor negative
1892 768 100 100     5272 ($x->{sign} eq '+' && !$x -> is_zero()) ? 1 : 0;
1893             }
1894              
1895             sub is_negative {
1896             # return true when arg (BINT or num_str) is negative (< 0)
1897 4449 100   4449 1 18977 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1898              
1899 4449 100       27720 $x->{sign} =~ /^-/ ? 1 : 0; # -inf is negative, but NaN is not
1900             }
1901              
1902             sub is_non_positive {
1903             # Return true if argument is non-positive (<= 0).
1904 64 100   64 1 7354 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1905              
1906 64 100       487 return 1 if $x->{sign} =~ /^\-/;
1907 40 100       144 return 1 if $x -> is_zero();
1908 32         385 return 0;
1909             }
1910              
1911             sub is_non_negative {
1912             # Return true if argument is non-negative (>= 0).
1913 64 100   64 1 6938 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1914              
1915 64 100       667 return 1 if $x->{sign} =~ /^\+/;
1916 32 50       129 return 1 if $x -> is_zero();
1917 32         402 return 0;
1918             }
1919              
1920             sub is_odd {
1921             # return true when arg (BINT or num_str) is odd, false for even
1922 185 50   185 1 1252 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1923              
1924 185 100       619 return 0 unless $x -> is_finite();
1925 178 100       824 $LIB->_is_odd($x->{value}) ? 1 : 0;
1926             }
1927              
1928             sub is_even {
1929             # return true when arg (BINT or num_str) is even, false for odd
1930 44 50   44 1 684 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1931              
1932 44 100       152 return 0 unless $x -> is_finite();
1933 40 100       194 $LIB->_is_even($x->{value}) ? 1 : 0;
1934             }
1935              
1936             sub is_int {
1937             # return true when arg (BINT or num_str) is an integer
1938 862 50   862 1 3488 my (undef, $x) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
1939              
1940 862 100       2361 $x -> is_finite() ? 1 : 0;
1941             }
1942              
1943             ###############################################################################
1944             # Comparison methods
1945             ###############################################################################
1946              
1947             sub bcmp {
1948             # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort)
1949             # (BINT or num_str, BINT or num_str) return cond_code
1950              
1951             # set up parameters
1952 2501 100 66 2501 1 27725 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
1953             ? (ref($_[0]), @_)
1954             : objectify(2, @_);
1955              
1956 2501 50       7952 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
1957              
1958             ###########################################################################
1959             # Code for all classes that share the common interface.
1960             ###########################################################################
1961              
1962             # Unless both $x and $y are finite ...
1963              
1964 2501 100 100     6651 unless ($x -> is_finite() && $y -> is_finite()) {
1965             # handle +-inf and NaN
1966 333 100 100     967 return if $x -> is_nan() || $y -> is_nan();
1967 269 100 66     1409 return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
1968 226 100       640 return +1 if $x -> is_inf("+");
1969 130 100       454 return -1 if $x -> is_inf("-");
1970 19 100       59 return -1 if $y -> is_inf("+");
1971 11         108 return +1;
1972             }
1973              
1974             # check sign for speed first
1975 2168 100 100     13810 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
1976 1906 100 100     20078 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
1977              
1978             ###########################################################################
1979             # Code for things that aren't Math::BigInt
1980             ###########################################################################
1981              
1982             # If called with "foreign" arguments.
1983              
1984 1700 100       8154 unless ($y -> isa(__PACKAGE__)) {
1985 1 50       5 if ($y -> is_int()) {
1986 0         0 $y = $y -> as_int();
1987             } else {
1988 1 50       6 return $x -> _upg() -> bcmp($y, @r) if $class -> upgrade();
1989 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
1990             }
1991             }
1992              
1993             ###########################################################################
1994             # Code for Math::BigInt objects
1995             ###########################################################################
1996              
1997             # post-normalized compare for internal use (honors signs)
1998 1699 100       4307 if ($x->{sign} eq '+') {
1999             # $x and $y both > 0
2000 1606         7946 return $LIB->_acmp($x->{value}, $y->{value});
2001             }
2002              
2003             # $x && $y both < 0; use swapped acmp (lib returns 0, 1, -1)
2004 93         751 $LIB->_acmp($y->{value}, $x->{value});
2005             }
2006              
2007             sub bacmp {
2008             # Compares 2 values, ignoring their signs.
2009             # Returns one of undef, <0, =0, >0. (suitable for sort)
2010             # (BINT, BINT) return cond_code
2011              
2012             # set up parameters
2013 116 50 33 116 1 2096 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2014             ? (ref($_[0]), @_)
2015             : objectify(2, @_);
2016              
2017 116 50       320 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2018              
2019             ###########################################################################
2020             # Code for all classes that share the common interface.
2021             ###########################################################################
2022              
2023 116 100 100     305 if ((!$x -> is_finite()) || (!$y -> is_finite())) {
2024             # handle +-inf and NaN
2025 72 100 100     198 return if $x -> is_nan() || $y -> is_nan();
2026 44 100 100     582 return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
2027 28 100 66     345 return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
2028 12         160 return -1;
2029             }
2030              
2031             ###########################################################################
2032             # Code for things that aren't Math::BigInt
2033             ###########################################################################
2034              
2035             # If called with "foreign" arguments.
2036              
2037 44 50       217 unless ($y -> isa(__PACKAGE__)) {
2038 0 0       0 if ($y -> is_int()) {
2039 0         0 $y = $y -> as_int();
2040             } else {
2041 0 0       0 return $x -> _upg() -> bacmp($y, @r) if $class -> upgrade();
2042 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2043             }
2044             }
2045              
2046             ###########################################################################
2047             # Code for Math::BigInt objects
2048             ###########################################################################
2049              
2050 44         245 $LIB->_acmp($x->{value}, $y->{value}); # lib does only 0, 1, -1
2051             }
2052              
2053             sub beq {
2054 529 100 66 529 1 4167 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2055             ? (undef, @_)
2056             : objectify(2, @_);
2057              
2058 529 50       1668 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2059              
2060 529         2030 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
2061 529   100     5061 return defined($cmp) && !$cmp;
2062             }
2063              
2064             sub bne {
2065 18 50 33 18 1 118 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2066             ? (undef, @_)
2067             : objectify(2, @_);
2068              
2069 18 50       40 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2070              
2071 18         51 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
2072 18 50 33     127 return defined($cmp) && !$cmp ? '' : 1;
2073             }
2074              
2075             sub blt {
2076 1053 100 66 1053 1 8248 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2077             ? (undef, @_)
2078             : objectify(2, @_);
2079              
2080 1053 50       3648 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2081              
2082 1053         4026 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
2083 1053   100     11973 return defined($cmp) && $cmp < 0;
2084             }
2085              
2086             sub ble {
2087 1463 100 66 1463 1 8758 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2088             ? (undef, @_)
2089             : objectify(2, @_);
2090              
2091 1463 50       3641 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2092              
2093 1463         4590 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
2094 1463   100     13510 return defined($cmp) && $cmp <= 0;
2095             }
2096              
2097             sub bgt {
2098 1465 100 66 1465 1 9363 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2099             ? (undef, @_)
2100             : objectify(2, @_);
2101              
2102 1465 50       3873 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2103              
2104 1465         4965 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
2105 1465   66     12266 return defined($cmp) && $cmp > 0;
2106             }
2107              
2108             sub bge {
2109 356 100 66 356 1 2739 my (undef, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2110             ? (undef, @_)
2111             : objectify(2, @_);
2112              
2113 356 50       1212 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2114              
2115 356         1289 my $cmp = $x -> bcmp($y); # bcmp() upgrades if necessary
2116 356   100     3358 return defined($cmp) && $cmp >= 0;
2117             }
2118              
2119             ###############################################################################
2120             # Arithmetic methods
2121             ###############################################################################
2122              
2123             sub bneg {
2124             # negate number or make a negated number from string
2125 490 50   490 1 2961 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2126              
2127             ###########################################################################
2128             # Code for all classes that share the common interface.
2129             ###########################################################################
2130              
2131             # Don't modify constant (read-only) objects.
2132              
2133 490 50       2238 return $x if $x -> modify('bneg');
2134              
2135 490 100       1871 $x->{sign} =~ tr/+-/-+/ unless $x -> is_zero();
2136 490         1830 $x -> round(@r);
2137 490 50 100     3191 $x -> _dng() if ($x -> is_int() || $x -> is_inf() || $x -> is_nan());
      66        
2138 490         3391 return $x;
2139             }
2140              
2141             sub babs {
2142             # (BINT or num_str) return BINT
2143             # make number absolute, or return absolute BINT from string
2144 891 100   891 1 8822 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2145              
2146             # Don't modify constant (read-only) objects.
2147              
2148 891 50       3140 return $x if $x -> modify('babs');
2149              
2150 891         3306 $x->{sign} =~ s/^-/+/;
2151              
2152 891         3061 $x -> round(@r);
2153 891 100 100     2306 $x -> _dng() if ($x -> is_int() || $x -> is_inf() || $x -> is_nan());
      100        
2154 891         13136 return $x;
2155             }
2156              
2157             sub bsgn {
2158             # Signum function.
2159 22 100   22 1 1321 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2160              
2161             # Don't modify constant (read-only) objects.
2162              
2163 22 50       85 return $x if $x -> modify('bsgn');
2164              
2165             # bone() downgrades, if necessary
2166              
2167 22 100       92 return $x -> bone("+", @r) if $x -> is_pos();
2168 12 100       40 return $x -> bone("-", @r) if $x -> is_neg();
2169              
2170 6         179 $x -> round(@r);
2171 6 100       18 $x -> _dng() if $x -> is_int();
2172 6         98 return $x;
2173             }
2174              
2175             sub bnorm {
2176             # (numstr or BINT) return BINT
2177             # Normalize number -- no-op here
2178 800 100   800 1 389661 my ($class, $x, @r) = ref($_[0]) ? (undef, $_[0]) : objectify(1, @_);
2179              
2180             # This method is called from the rounding methods, so if this method
2181             # supports rounding by calling the rounding methods, we get an infinite
2182             # recursion.
2183              
2184 800 50       2737 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
2185              
2186 800         10423 $x;
2187             }
2188              
2189             sub binc {
2190             # increment arg by one
2191 190 50   190 1 898 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2192              
2193             ###########################################################################
2194             # Code for all classes that share the common interface.
2195             ###########################################################################
2196              
2197             # Don't modify constant (read-only) objects.
2198              
2199 190 50       722 return $x if $x -> modify('binc');
2200              
2201 190 100 100     602 return $x -> round(@r) if $x -> is_inf() || $x -> is_nan();
2202              
2203             ###########################################################################
2204             # Code for Math::BigInt objects
2205             ###########################################################################
2206              
2207 174 100       613 if ($x->{sign} eq '+') {
    50          
2208 100         517 $x->{value} = $LIB->_inc($x->{value});
2209             } elsif ($x->{sign} eq '-') {
2210 74         299 $x->{value} = $LIB->_dec($x->{value});
2211 74 100       300 $x->{sign} = '+' if $LIB->_is_zero($x->{value}); # -1 +1 => -0 => +0
2212             }
2213              
2214 174         504 return $x -> round(@r);
2215             }
2216              
2217             sub bdec {
2218             # decrement arg by one
2219 31 50   31 1 346 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
2220              
2221             ###########################################################################
2222             # Code for all classes that share the common interface.
2223             ###########################################################################
2224              
2225             # Don't modify constant (read-only) objects.
2226              
2227 31 50       149 return $x if $x -> modify('bdec');
2228              
2229 31 100 100     94 return $x -> round(@r) if $x -> is_inf() || $x -> is_nan();
2230              
2231             ###########################################################################
2232             # Code for Math::BigInt objects
2233             ###########################################################################
2234              
2235 19 100       135 if ($x->{sign} eq '-') {
    50          
2236 4         37 $x->{value} = $LIB->_inc($x->{value});
2237             } elsif ($x->{sign} eq '+') {
2238 15 100       77 if ($LIB->_is_zero($x->{value})) { # +1 - 1 => +0
2239 4         21 $x->{value} = $LIB->_one();
2240 4         44 $x->{sign} = '-';
2241             } else {
2242 11         183 $x->{value} = $LIB->_dec($x->{value});
2243             }
2244             }
2245              
2246 19         65 return $x -> round(@r);
2247             }
2248              
2249             #sub bstrcmp {
2250             # my $self = shift;
2251             # my $selfref = ref $self;
2252             # my $class = $selfref || $self;
2253             #
2254             # croak 'bstrcmp() is an instance method, not a class method'
2255             # unless $selfref;
2256             # croak 'Wrong number of arguments for bstrcmp()' unless @_ == 1;
2257             #
2258             # return $self -> bstr() CORE::cmp shift;
2259             #}
2260             #
2261             #sub bstreq {
2262             # my $self = shift;
2263             # my $selfref = ref $self;
2264             # my $class = $selfref || $self;
2265             #
2266             # croak 'bstreq() is an instance method, not a class method'
2267             # unless $selfref;
2268             # croak 'Wrong number of arguments for bstreq()' unless @_ == 1;
2269             #
2270             # my $cmp = $self -> bstrcmp(shift);
2271             # return defined($cmp) && ! $cmp;
2272             #}
2273             #
2274             #sub bstrne {
2275             # my $self = shift;
2276             # my $selfref = ref $self;
2277             # my $class = $selfref || $self;
2278             #
2279             # croak 'bstrne() is an instance method, not a class method'
2280             # unless $selfref;
2281             # croak 'Wrong number of arguments for bstrne()' unless @_ == 1;
2282             #
2283             # my $cmp = $self -> bstrcmp(shift);
2284             # return defined($cmp) && ! $cmp ? '' : 1;
2285             #}
2286             #
2287             #sub bstrlt {
2288             # my $self = shift;
2289             # my $selfref = ref $self;
2290             # my $class = $selfref || $self;
2291             #
2292             # croak 'bstrlt() is an instance method, not a class method'
2293             # unless $selfref;
2294             # croak 'Wrong number of arguments for bstrlt()' unless @_ == 1;
2295             #
2296             # my $cmp = $self -> bstrcmp(shift);
2297             # return defined($cmp) && $cmp < 0;
2298             #}
2299             #
2300             #sub bstrle {
2301             # my $self = shift;
2302             # my $selfref = ref $self;
2303             # my $class = $selfref || $self;
2304             #
2305             # croak 'bstrle() is an instance method, not a class method'
2306             # unless $selfref;
2307             # croak 'Wrong number of arguments for bstrle()' unless @_ == 1;
2308             #
2309             # my $cmp = $self -> bstrcmp(shift);
2310             # return defined($cmp) && $cmp <= 0;
2311             #}
2312             #
2313             #sub bstrgt {
2314             # my $self = shift;
2315             # my $selfref = ref $self;
2316             # my $class = $selfref || $self;
2317             #
2318             # croak 'bstrgt() is an instance method, not a class method'
2319             # unless $selfref;
2320             # croak 'Wrong number of arguments for bstrgt()' unless @_ == 1;
2321             #
2322             # my $cmp = $self -> bstrcmp(shift);
2323             # return defined($cmp) && $cmp > 0;
2324             #}
2325             #
2326             #sub bstrge {
2327             # my $self = shift;
2328             # my $selfref = ref $self;
2329             # my $class = $selfref || $self;
2330             #
2331             # croak 'bstrge() is an instance method, not a class method'
2332             # unless $selfref;
2333             # croak 'Wrong number of arguments for bstrge()' unless @_ == 1;
2334             #
2335             # my $cmp = $self -> bstrcmp(shift);
2336             # return defined($cmp) && $cmp >= 0;
2337             #}
2338              
2339             sub badd {
2340             # add second arg (BINT or string) to first (BINT) (modifies first)
2341             # return result as BINT
2342              
2343             # set up parameters
2344 733 100 100 733 1 10861 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2345             ? (ref($_[0]), @_)
2346             : objectify(2, @_);
2347              
2348 733 50       3748 return $x -> badd($y, @r) unless $x -> isa(__PACKAGE__);
2349              
2350             ###########################################################################
2351             # Code for all classes that share the common interface.
2352             ###########################################################################
2353              
2354             # Don't modify constant (read-only) objects.
2355              
2356 733 50       2693 return $x if $x -> modify('badd');
2357              
2358 733         1765 $r[3] = $y; # no push!
2359              
2360 733 100 100     2190 unless ($x -> is_finite() && $y -> is_finite()) {
2361              
2362 125 100 100     405 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
2363              
2364 70 100       235 return $x -> is_inf("+") ? ($y -> is_inf("-") ? $x -> bnan(@r)
    100          
    100          
    100          
    100          
2365             : $x -> binf("+", @r))
2366             : $x -> is_inf("-") ? ($y -> is_inf("+") ? $x -> bnan(@r)
2367             : $x -> binf("-", @r))
2368             : ($y -> is_inf("+") ? $x -> binf("+", @r)
2369             : $x -> binf("-", @r));
2370             }
2371              
2372             ###########################################################################
2373             # Code for things that aren't Math::BigInt
2374             ###########################################################################
2375              
2376             # If called with "foreign" arguments.
2377              
2378 608 100       2315 unless ($y -> isa(__PACKAGE__)) {
2379 2 50       8 if ($y -> is_int()) {
2380 0         0 $y = $y -> as_int();
2381             } else {
2382 2 50       9 return $x -> _upg() -> badd($y, @r) if $class -> upgrade();
2383 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2384             }
2385             }
2386              
2387             ###########################################################################
2388             # Code for Math::BigInt objects
2389             ###########################################################################
2390              
2391             ($x->{value}, $x->{sign})
2392 606         3794 = $LIB -> _sadd($x->{value}, $x->{sign}, $y->{value}, $y->{sign});
2393              
2394 606         2893 $x -> round(@r);
2395             }
2396              
2397             sub bsub {
2398             # (BINT or num_str, BINT or num_str) return BINT
2399             # subtract second arg from first, modify first
2400              
2401             # set up parameters
2402 1075 100 100 1075 1 11096 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2403             ? (ref($_[0]), @_)
2404             : objectify(2, @_);
2405              
2406 1075 50       4576 return $x -> bsub($y, @r) unless $x -> isa(__PACKAGE__);
2407              
2408             ###########################################################################
2409             # Code for all classes that share the common interface.
2410             ###########################################################################
2411              
2412             # Don't modify constant (read-only) objects.
2413              
2414 1075 50       3703 return $x if $x -> modify('bsub');
2415              
2416 1075         2209 $r[3] = $y; # no push!
2417              
2418 1075 100 100     3080 unless ($x -> is_finite() && $y -> is_finite()) {
2419              
2420 112 100 100     422 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
2421              
2422 73 100       224 return $x -> is_inf("+") ? ($y -> is_inf("+") ? $x -> bnan(@r)
    100          
    100          
    100          
    100          
2423             : $x -> binf("+", @r))
2424             : $x -> is_inf("-") ? ($y -> is_inf("-") ? $x -> bnan(@r)
2425             : $x -> binf("-", @r))
2426             : ($y -> is_inf("+") ? $x -> binf("-", @r)
2427             : $x -> binf("+", @r));
2428             }
2429              
2430 963 100       3561 return $x -> bzero(@r) if refaddr($x) eq refaddr($y); # $x -> bsub($x)
2431              
2432             ###########################################################################
2433             # Code for things that aren't Math::BigInt
2434             ###########################################################################
2435              
2436             # If called with "foreign" arguments.
2437              
2438 957 50       3238 unless ($y -> isa(__PACKAGE__)) {
2439 0 0       0 if ($y -> is_int()) {
2440 0         0 $y = $y -> as_int();
2441             } else {
2442 0 0       0 return $x -> _upg() -> bsub($y, @r) if $class -> upgrade();
2443 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2444             }
2445             }
2446              
2447             ###########################################################################
2448             # Code for Math::BigInt objects
2449             ###########################################################################
2450              
2451             ($x->{value}, $x->{sign})
2452 957         5177 = $LIB -> _ssub($x->{value}, $x->{sign}, $y->{value}, $y->{sign});
2453              
2454 957         4353 $x -> round(@r);
2455             }
2456              
2457             sub bmul {
2458             # multiply the first number by the second number
2459             # (BINT or num_str, BINT or num_str) return BINT
2460              
2461             # set up parameters
2462 1458 100 100 1458 1 12376 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2463             ? (ref($_[0]), @_)
2464             : objectify(2, @_);
2465              
2466             ###########################################################################
2467             # Code for all classes that share the common interface.
2468             ###########################################################################
2469              
2470             # Don't modify constant (read-only) objects.
2471              
2472 1458 50       5563 return $x if $x -> modify('bmul');
2473              
2474 1458 50       5350 return $x -> bmul($y, @r) unless $x -> isa(__PACKAGE__);
2475              
2476 1458 100 100     3796 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
2477              
2478             # inf handling
2479 1406 100 100     7133 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/)) {
2480 52 100 100     224 return $x -> bnan(@r) if $x -> is_zero() || $y -> is_zero();
2481             # result will always be +-inf:
2482             # +inf * +/+inf => +inf, -inf * -/-inf => +inf
2483             # +inf * -/-inf => -inf, -inf * +/+inf => -inf
2484 40 100 100     276 return $x -> binf(@r) if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
2485 30 100 100     243 return $x -> binf(@r) if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
2486 20         73 return $x -> binf('-', @r);
2487             }
2488              
2489             ###########################################################################
2490             # Code for things that aren't Math::BigInt
2491             ###########################################################################
2492              
2493             # If called with "foreign" arguments.
2494              
2495 1354 100       3887 unless ($y -> isa(__PACKAGE__)) {
2496 1 50       5 if ($y -> is_int()) {
2497 0         0 $y = $y -> as_int();
2498             } else {
2499 1 50       4 return $x -> _upg() -> bmul($y, @r) if $class -> upgrade();
2500 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2501             }
2502             }
2503              
2504             ###########################################################################
2505             # Code for Math::BigInt objects
2506             ###########################################################################
2507              
2508 1353         2529 $r[3] = $y; # no push here
2509              
2510 1353 100       3859 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
2511              
2512 1353         5859 $x->{value} = $LIB->_mul($x->{value}, $y->{value}); # do actual math
2513 1353 100       4776 $x->{sign} = '+' if $LIB->_is_zero($x->{value}); # no -0
2514              
2515 1353         5794 $x -> round(@r);
2516             }
2517              
2518             *bdiv = \&bfdiv;
2519             *bmod = \&bfmod;
2520              
2521             sub bfdiv {
2522             # This does floored division, where the quotient is floored, i.e., rounded
2523             # towards negative infinity. As a consequence, the remainder has the same
2524             # sign as the divisor.
2525             #
2526             # ($q, $r) = $x -> btdiv($y) returns $q and $r so that $q is floor($x / $y)
2527             # and $q * $y + $r = $x.
2528              
2529             # Set up parameters.
2530 1464 100 100 1464 1 46227 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2531             ? (ref($_[0]), @_)
2532             : objectify(2, @_);
2533              
2534             ###########################################################################
2535             # Code for all classes that share the common interface.
2536             ###########################################################################
2537              
2538             # Don't modify constant (read-only) objects.
2539              
2540 1464 50       6166 return $x if $x -> modify('bfdiv');
2541              
2542 1464         3038 my $wantarray = wantarray; # call only once
2543              
2544             # At least one argument is NaN. Return NaN for both quotient and the
2545             # modulo/remainder.
2546              
2547 1464 100 100     4495 if ($x -> is_nan() || $y -> is_nan()) {
2548 51 100       303 return $wantarray ? ($x -> bnan(@r), $class -> bnan(@r))
2549             : $x -> bnan(@r);
2550             }
2551              
2552             # Divide by zero and modulo zero.
2553             #
2554             # Division: Use the common convention that x / 0 is inf with the same sign
2555             # as x, except when x = 0, where we return NaN. This is also what earlier
2556             # versions did.
2557             #
2558             # Modulo: In modular arithmetic, the congruence relation z = x (mod y)
2559             # means that there is some integer k such that z - x = k y. If y = 0, we
2560             # get z - x = 0 or z = x. This is also what earlier versions did, except
2561             # that 0 % 0 returned NaN.
2562             #
2563             # inf / 0 = inf inf % 0 = inf
2564             # 5 / 0 = inf 5 % 0 = 5
2565             # 0 / 0 = NaN 0 % 0 = 0
2566             # -5 / 0 = -inf -5 % 0 = -5
2567             # -inf / 0 = -inf -inf % 0 = -inf
2568              
2569 1413 100       4993 if ($y -> is_zero()) {
2570 68         160 my $rem;
2571 68 100       283 if ($wantarray) {
2572 32         132 $rem = $x -> copy() -> round(@r);
2573             }
2574 68 100       222 if ($x -> is_zero()) {
2575 18         97 $x -> bnan(@r);
2576             } else {
2577 50         197 $x -> binf($x -> {sign}, @r);
2578             }
2579 64 100       769 return $wantarray ? ($x, $rem) : $x;
2580             }
2581              
2582             # Numerator (dividend) is +/-inf, and denominator is finite and non-zero.
2583             # The divide by zero cases are covered above. In all of the cases listed
2584             # below we return the same as core Perl.
2585             #
2586             # inf / -inf = NaN inf % -inf = NaN
2587             # inf / -5 = -inf inf % -5 = NaN
2588             # inf / 5 = inf inf % 5 = NaN
2589             # inf / inf = NaN inf % inf = NaN
2590             #
2591             # -inf / -inf = NaN -inf % -inf = NaN
2592             # -inf / -5 = inf -inf % -5 = NaN
2593             # -inf / 5 = -inf -inf % 5 = NaN
2594             # -inf / inf = NaN -inf % inf = NaN
2595              
2596 1345 100       3947 if ($x -> is_inf()) {
2597 96         224 my $rem;
2598 96 100       410 $rem = $class -> bnan(@r) if $wantarray;
2599 96 100       270 if ($y -> is_inf()) {
2600 48         166 $x -> bnan(@r);
2601             } else {
2602 48 100       212 my $sign = $x -> bcmp(0) == $y -> bcmp(0) ? '+' : '-';
2603 48         173 $x -> binf($sign, @r);
2604             }
2605 96 100       999 return $wantarray ? ($x, $rem) : $x;
2606             }
2607              
2608             # Denominator (divisor) is +/-inf. The cases when the numerator is +/-inf
2609             # are covered above. In the modulo cases (in the right column) we return
2610             # the same as core Perl, which does floored division, so for consistency we
2611             # also do floored division in the division cases (in the left column).
2612             #
2613             # -5 / inf = -1 -5 % inf = inf
2614             # 0 / inf = 0 0 % inf = 0
2615             # 5 / inf = 0 5 % inf = 5
2616             #
2617             # -5 / -inf = 0 -5 % -inf = -5
2618             # 0 / -inf = 0 0 % -inf = 0
2619             # 5 / -inf = -1 5 % -inf = -inf
2620              
2621 1249 100       2774 if ($y -> is_inf()) {
2622 80         188 my $rem;
2623 80 100 100     242 if ($x -> is_zero() || $x -> bcmp(0) == $y -> bcmp(0)) {
2624 56 100       1945 $rem = $x -> copy() -> round(@r) if $wantarray;
2625 56         262 $x -> bzero(@r);
2626             } else {
2627 24 100       148 $rem = $class -> binf($y -> {sign}, @r) if $wantarray;
2628 24         132 $x -> bone('-', @r);
2629             }
2630 80 100       738 return $wantarray ? ($x, $rem) : $x;
2631             }
2632              
2633             ###########################################################################
2634             # Code for things that aren't Math::BigInt
2635             ###########################################################################
2636              
2637             # At this point, both the numerator and denominator are finite, non-zero
2638             # numbers.
2639              
2640 1169 100       3048 unless ($wantarray) {
2641 665         2446 my $upg = $class -> upgrade();
2642 665 100       2207 if ($upg) {
2643 55         490 my $tmp = $upg -> bfdiv($x, $y, @r);
2644 55 100       181 if ($tmp -> is_int()) {
2645 21         100 $tmp = $tmp -> as_int();
2646 21         206 %$x = %$tmp;
2647             } else {
2648 34         310 %$x = %$tmp;
2649 34         113 bless $x, $upg;
2650             }
2651 55         1622 return $x;
2652             }
2653             }
2654              
2655             # If called with "foreign" arguments.
2656              
2657 1114 50       4655 unless ($y -> isa(__PACKAGE__)) {
2658 0 0       0 if ($y -> is_int()) {
2659 0         0 $y = $y -> as_int();
2660             } else {
2661 0 0       0 return $x -> _upg() -> bfdiv($y, @r) if $class -> upgrade();
2662 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2663             }
2664             }
2665              
2666             ###########################################################################
2667             # Code for Math::BigInt objects
2668             ###########################################################################
2669              
2670 1114         2287 $r[3] = $y; # no push!
2671              
2672             # Initialize remainder.
2673              
2674 1114         3753 my $rem = $class -> bzero();
2675              
2676             # Are both operands the same object, i.e., like $x -> bfdiv($x)? If so,
2677             # flipping the sign of $y also flips the sign of $x.
2678              
2679 1114         2715 my $xsign = $x -> {sign};
2680 1114         2322 my $ysign = $y -> {sign};
2681              
2682 1114         3150 $y -> {sign} =~ tr/+-/-+/; # Flip the sign of $y, and see ...
2683 1114         2720 my $same = $xsign ne $x -> {sign}; # ... if that changed the sign of $x.
2684 1114         2363 $y -> {sign} = $ysign; # Restore the original sign.
2685              
2686 1114 100       2416 if ($same) { # $x -> bfdiv($x)
2687 6         27 $x -> bone();
2688             } else {
2689              
2690             # Compute quotient and remainder, ignoring signs.
2691              
2692             ($x -> {value}, $rem -> {value}) =
2693 1108         5093 $LIB -> _div($x -> {value}, $y -> {value});
2694              
2695             # x y q r
2696             # 23 / 7 => 3 2
2697             # -23 / 7 => -4 5
2698             # 23 / -7 => -4 -5
2699             # -23 / -7 => 3 -2
2700              
2701             # We are doing floored division, so adjust quotient and remainder as
2702             # necessary.
2703              
2704 1108 100 100     3881 if ($xsign ne $ysign && !$LIB -> _is_zero($rem -> {value})) {
2705 53         316 $x -> {value} = $LIB -> _inc($x -> {value});
2706             $rem -> {value} = $LIB -> _sub($LIB -> _copy($y -> {value}),
2707 53         247 $rem -> {value});
2708             }
2709              
2710             # Now do the signs.
2711              
2712             $x -> {sign} = $xsign eq $ysign || $LIB -> _is_zero($x -> {value})
2713 1108 100 100     4055 ? '+' : '-';
2714             $rem -> {sign} = $ysign eq '+' || $LIB -> _is_zero($rem -> {value})
2715 1108 100 100     4097 ? '+' : '-';
2716             }
2717              
2718             # List context.
2719              
2720 1114 100       2802 if ($wantarray) {
2721 504         1124 $rem -> {accuracy} = $x -> {accuracy};
2722 504         1072 $rem -> {precision} = $x -> {precision};
2723 504         2531 $x -> round(@r);
2724 504         1496 $rem -> round(@r);
2725 504         3307 return $x, $rem;
2726             }
2727              
2728             # Scalar context.
2729              
2730 610 100       3335 return $x -> round(@r) if $LIB -> _is_zero($rem -> {value});
2731              
2732             # We could use this instead of the upgrade code above, but this code gives
2733             # more decimals when the integer part is non-zero. This is because the
2734             # fraction part is divided separately and the rounding is done on that part
2735             # separeately before the integer part is added.
2736             #
2737             #if ($class -> upgrade()) {
2738             # $rem -> _upg() -> bfdiv($y);
2739             # $x -> _upg() -> badd($rem, @r);
2740             # return $x;
2741             #}
2742              
2743 196         1189 $x -> round(@r);
2744 196         3696 return $x;
2745             }
2746              
2747             sub bfmod {
2748             # This is the remainder after floored division.
2749              
2750             # Set up parameters.
2751 764 100 100 764 1 6923 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2752             ? (ref($_[0]), @_)
2753             : objectify(2, @_);
2754              
2755             ###########################################################################
2756             # Code for all classes that share the common interface.
2757             ###########################################################################
2758              
2759             # Don't modify constant (read-only) objects.
2760              
2761 764 50       3578 return $x if $x -> modify('bfmod');
2762              
2763 764         1728 $r[3] = $y; # no push!
2764              
2765             # At least one argument is NaN.
2766              
2767 764 100 100     2460 if ($x -> is_nan() || $y -> is_nan()) {
2768 27         161 return $x -> bnan(@r);
2769             }
2770              
2771             # Modulo zero. See documentation for bfdiv().
2772              
2773 737 100       4880 if ($y -> is_zero()) {
2774 34         161 return $x -> round(@r);
2775             }
2776              
2777             # Numerator (dividend) is +/-inf.
2778              
2779 703 100       2063 if ($x -> is_inf()) {
2780 48         292 return $x -> bnan(@r);
2781             }
2782              
2783             # Denominator (divisor) is +/-inf.
2784              
2785 655 100       1570 if ($y -> is_inf()) {
2786 40 100 100     111 if ($x -> is_zero() || $x -> bcmp(0) == $y -> bcmp(0)) {
2787 28         153 return $x -> round(@r);
2788             } else {
2789 12         103 return $x -> binf($y -> sign(), @r);
2790             }
2791             }
2792              
2793             ###########################################################################
2794             # Code for things that aren't Math::BigInt
2795             ###########################################################################
2796              
2797             # If called with "foreign" arguments.
2798              
2799 615 50       2613 unless ($y -> isa(__PACKAGE__)) {
2800 0 0       0 if ($y -> is_int()) {
2801 0         0 $y = $y -> as_int();
2802             } else {
2803 0 0       0 return $x -> _upg() -> bfmod($y, @r) if $class -> upgrade();
2804 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2805             }
2806             }
2807              
2808             ###########################################################################
2809             # Code for Math::BigInt objects
2810             ###########################################################################
2811              
2812             # Calc new sign and in case $y == +/- 1, return $x.
2813              
2814 615         2906 $x -> {value} = $LIB -> _mod($x -> {value}, $y -> {value});
2815 615 100       2089 if ($LIB -> _is_zero($x -> {value})) {
2816 154         440 $x -> {sign} = '+'; # do not leave -0
2817             } else {
2818             $x -> {value} = $LIB -> _sub($y -> {value}, $x -> {value}, 1) # $y-$x
2819 461 100       1889 if ($x -> {sign} ne $y -> {sign});
2820 461         1039 $x -> {sign} = $y -> {sign};
2821             }
2822              
2823 615         3009 $x -> round(@r);
2824             }
2825              
2826             sub btdiv {
2827             # This does truncated division, where the quotient is truncted, i.e.,
2828             # rounded towards zero.
2829             #
2830             # ($q, $r) = $x -> btdiv($y) returns $q and $r so that $q is int($x / $y)
2831             # and $q * $y + $r = $x.
2832              
2833             # Set up parameters
2834 366 50 33 366 1 8207 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
2835             ? (ref($_[0]), @_)
2836             : objectify(2, @_);
2837              
2838             ###########################################################################
2839             # Code for all classes that share the common interface.
2840             ###########################################################################
2841              
2842             # Don't modify constant (read-only) objects.
2843              
2844 366 50       1633 return $x if $x -> modify('btdiv');
2845              
2846 366         886 my $wantarray = wantarray; # call only once
2847              
2848             # At least one argument is NaN. Return NaN for both quotient and the
2849             # modulo/remainder.
2850              
2851 366 50 33     1277 if ($x -> is_nan() || $y -> is_nan()) {
2852 0 0       0 return $wantarray ? ($x -> bnan(@r), $class -> bnan(@r))
2853             : $x -> bnan(@r);
2854             }
2855              
2856             # Divide by zero and modulo zero.
2857             #
2858             # Division: Use the common convention that x / 0 is inf with the same sign
2859             # as x, except when x = 0, where we return NaN. This is also what earlier
2860             # versions did.
2861             #
2862             # Modulo: In modular arithmetic, the congruence relation z = x (mod y)
2863             # means that there is some integer k such that z - x = k y. If y = 0, we
2864             # get z - x = 0 or z = x. This is also what earlier versions did, except
2865             # that 0 % 0 returned NaN.
2866             #
2867             # inf / 0 = inf inf % 0 = inf
2868             # 5 / 0 = inf 5 % 0 = 5
2869             # 0 / 0 = NaN 0 % 0 = 0
2870             # -5 / 0 = -inf -5 % 0 = -5
2871             # -inf / 0 = -inf -inf % 0 = -inf
2872              
2873 366 100       1105 if ($y -> is_zero()) {
2874 30         71 my $rem;
2875 30 100       97 if ($wantarray) {
2876 15         53 $rem = $x -> copy(@r);
2877             }
2878 30 100       82 if ($x -> is_zero()) {
2879 6         59 $x -> bnan(@r);
2880             } else {
2881 24         92 $x -> binf($x -> {sign}, @r);
2882             }
2883 30 100       374 return $wantarray ? ($x, $rem) : $x;
2884             }
2885              
2886             # Numerator (dividend) is +/-inf, and denominator is finite and non-zero.
2887             # The divide by zero cases are covered above. In all of the cases listed
2888             # below we return the same as core Perl.
2889             #
2890             # inf / -inf = NaN inf % -inf = NaN
2891             # inf / -5 = -inf inf % -5 = NaN
2892             # inf / 5 = inf inf % 5 = NaN
2893             # inf / inf = NaN inf % inf = NaN
2894             #
2895             # -inf / -inf = NaN -inf % -inf = NaN
2896             # -inf / -5 = inf -inf % -5 = NaN
2897             # -inf / 5 = -inf -inf % 5 = NaN
2898             # -inf / inf = NaN -inf % inf = NaN
2899              
2900 336 100       990 if ($x -> is_inf()) {
2901 48         100 my $rem;
2902 48 100       191 $rem = $class -> bnan(@r) if $wantarray;
2903 48 100       151 if ($y -> is_inf()) {
2904 24         88 $x -> bnan(@r);
2905             } else {
2906 24 100       110 my $sign = $x -> bcmp(0) == $y -> bcmp(0) ? '+' : '-';
2907 24         92 $x -> binf($sign,@r );
2908             }
2909 48 100       593 return $wantarray ? ($x, $rem) : $x;
2910             }
2911              
2912             # Denominator (divisor) is +/-inf. The cases when the numerator is +/-inf
2913             # are covered above. In the modulo cases (in the right column) we return
2914             # the same as core Perl, which does floored division, so for consistency we
2915             # also do floored division in the division cases (in the left column).
2916             #
2917             # -5 / inf = 0 -5 % inf = -5
2918             # 0 / inf = 0 0 % inf = 0
2919             # 5 / inf = 0 5 % inf = 5
2920             #
2921             # -5 / -inf = 0 -5 % -inf = -5
2922             # 0 / -inf = 0 0 % -inf = 0
2923             # 5 / -inf = 0 5 % -inf = 5
2924              
2925 288 100       710 if ($y -> is_inf()) {
2926 36         68 my $rem;
2927 36 100       204 $rem = $x -> copy() -> round(@r) if $wantarray;
2928 36         146 $x -> bzero(@r);
2929 36 100       449 return $wantarray ? ($x, $rem) : $x;
2930             }
2931              
2932             ###########################################################################
2933             # Code for things that aren't Math::BigInt
2934             ###########################################################################
2935              
2936             # Division might return a non-integer result, so upgrade, if upgrading is
2937             # enabled.
2938              
2939 252 100       789 unless ($wantarray) {
2940 126         483 my $upg = $class -> upgrade();
2941 126 50       379 if ($upg) {
2942 0         0 my $tmp = $upg -> btdiv($x, $y, @r);
2943 0 0       0 if ($tmp -> is_int()) {
2944 0         0 $tmp = $tmp -> as_int();
2945 0         0 %$x = %$tmp;
2946             } else {
2947 0         0 %$x = %$tmp;
2948 0         0 bless $x, $upg;
2949             }
2950 0         0 return $x;
2951             }
2952             }
2953              
2954             # If called with "foreign" arguments.
2955              
2956 252 50       1390 unless ($y -> isa(__PACKAGE__)) {
2957 0 0       0 if ($y -> is_int()) {
2958 0         0 $y = $y -> as_int();
2959             } else {
2960 0 0       0 return $x -> _upg() -> btdiv($y, @r) if $class -> upgrade();
2961 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
2962             }
2963             }
2964              
2965             ###########################################################################
2966             # Code for Math::BigInt objects objects
2967             ###########################################################################
2968              
2969 252         532 $r[3] = $y; # no push!
2970              
2971             # Initialize remainder.
2972              
2973 252         923 my $rem = $class -> bzero();
2974              
2975             # Are both operands the same object, i.e., like $x -> btdiv($x)? If so,
2976             # flipping the sign of $y also flips the sign of $x.
2977              
2978 252         654 my $xsign = $x -> {sign};
2979 252         561 my $ysign = $y -> {sign};
2980              
2981 252         734 $y -> {sign} =~ tr/+-/-+/; # Flip the sign of $y, and see ...
2982 252         594 my $same = $xsign ne $x -> {sign}; # ... if that changed the sign of $x.
2983 252         580 $y -> {sign} = $ysign; # Re-insert the original sign.
2984              
2985 252 50       577 if ($same) {
2986 0         0 $x -> bone(@r);
2987             } else {
2988             ($x -> {value}, $rem -> {value}) =
2989 252         1252 $LIB -> _div($x -> {value}, $y -> {value});
2990              
2991 252 100       873 $x -> {sign} = $xsign eq $ysign ? '+' : '-';
2992 252 100       3361 $x -> {sign} = '+' if $LIB -> _is_zero($x -> {value});
2993 252         1277 $x -> round(@r);
2994             }
2995              
2996 252 100       847 if ($wantarray) {
2997 126         340 $rem -> {sign} = $xsign;
2998 126 100       592 $rem -> {sign} = '+' if $LIB -> _is_zero($rem -> {value});
2999 126         324 $rem -> {accuracy} = $x -> {accuracy};
3000 126         251 $rem -> {precision} = $x -> {precision};
3001 126         439 $rem -> round(@r);
3002 126         1074 return $x, $rem;
3003             }
3004              
3005 126         2236 return $x;
3006             }
3007              
3008             sub btmod {
3009             # Remainder after truncated division.
3010              
3011             # set up parameters
3012 0 0 0 0 1 0 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3013             ? (ref($_[0]), @_)
3014             : objectify(2, @_);
3015              
3016             ###########################################################################
3017             # Code for all classes that share the common interface.
3018             ###########################################################################
3019              
3020             # Don't modify constant (read-only) objects.
3021              
3022 0 0       0 return $x if $x -> modify('btmod');
3023              
3024 0         0 $r[3] = $y; # no push!
3025              
3026             # At least one argument is NaN.
3027              
3028 0 0 0     0 if ($x -> is_nan() || $y -> is_nan()) {
3029 0         0 return $x -> bnan(@r);
3030             }
3031              
3032             # Modulo zero. See documentation for btdiv().
3033              
3034 0 0       0 if ($y -> is_zero()) {
3035 0         0 return $x -> round(@r);
3036             }
3037              
3038             # Numerator (dividend) is +/-inf.
3039              
3040 0 0       0 if ($x -> is_inf()) {
3041 0         0 return $x -> bnan(@r);
3042             }
3043              
3044             # Denominator (divisor) is +/-inf.
3045              
3046 0 0       0 if ($y -> is_inf()) {
3047 0         0 return $x -> round(@r);
3048             }
3049              
3050             ###########################################################################
3051             # Code for things that aren't Math::BigInt
3052             ###########################################################################
3053              
3054             # If called with "foreign" arguments.
3055              
3056 0 0       0 unless ($y -> isa(__PACKAGE__)) {
3057 0 0       0 if ($y -> is_int()) {
3058 0         0 $y = $y -> as_int();
3059             } else {
3060 0 0       0 return $x -> _upg() -> btmod($y, @r) if $class -> upgrade();
3061 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
3062             }
3063             }
3064              
3065             ###########################################################################
3066             # Code for Math::BigInt objects
3067             ###########################################################################
3068              
3069 0         0 my $xsign = $x -> {sign};
3070              
3071 0         0 $x -> {value} = $LIB -> _mod($x -> {value}, $y -> {value});
3072              
3073 0         0 $x -> {sign} = $xsign;
3074 0 0       0 $x -> {sign} = '+' if $LIB -> _is_zero($x -> {value});
3075 0         0 $x -> round(@r);
3076             }
3077              
3078             sub binv {
3079 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), $_[0]) : objectify(1, @_);
3080              
3081             ###########################################################################
3082             # Code for all classes that share the common interface.
3083             ###########################################################################
3084              
3085             # Don't modify constant (read-only) objects.
3086              
3087 0 0       0 return $x if $x -> modify('binv');
3088              
3089 0 0       0 return $x -> binf("+", @r) if $x -> is_zero();
3090 0 0       0 return $x -> bzero(@r) if $x -> is_inf();
3091 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
3092 0 0 0     0 return $x -> round(@r) if $x -> is_one("+") || $x -> is_one("-");
3093              
3094             ###########################################################################
3095             # Output might be finite, non-integer, so upgrade.
3096             ###########################################################################
3097              
3098 0 0       0 return $x -> _upg() -> binv(@r) if $class -> upgrade();
3099              
3100             ###########################################################################
3101             # Code for things that aren't Math::BigInt
3102             ###########################################################################
3103              
3104 0 0       0 unless ($x -> isa(__PACKAGE__)) {
3105 0         0 croak "Can't handle a ", ref($x), " in ", (caller(0))[3], "()";
3106             }
3107              
3108             ###########################################################################
3109             # Code for Math::BigInt objects
3110             ###########################################################################
3111              
3112 0         0 $x -> bzero(@r);
3113             }
3114              
3115             sub bsqrt {
3116             # calculate square root of $x
3117 122 100   122 1 5676 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3118              
3119             ###########################################################################
3120             # Code for all classes that share the common interface.
3121             ###########################################################################
3122              
3123             # Don't modify constant (read-only) objects.
3124              
3125 122 50       565 return $x if $x -> modify('bsqrt');
3126              
3127 122 100 100     453 return $x -> round(@r) if ($x -> is_zero() || $x -> is_one("+") ||
      100        
      100        
3128             $x -> is_nan() || $x -> is_inf("+"));
3129 106 100       386 return $x -> bnan(@r) if $x -> is_negative();
3130              
3131             ###########################################################################
3132             # Output might be finite, non-integer, so upgrade.
3133             ###########################################################################
3134              
3135 94 100       308 return $x -> _upg() -> bsqrt(@r) if $class -> upgrade();
3136              
3137             ###########################################################################
3138             # Code for things that aren't Math::BigInt
3139             ###########################################################################
3140              
3141 75 50       345 unless ($x -> isa(__PACKAGE__)) {
3142 0         0 croak "Can't handle a ", ref($x), " in ", (caller(0))[3], "()";
3143             }
3144              
3145             ###########################################################################
3146             # Code for Math::BigInt objects
3147             ###########################################################################
3148              
3149 75         433 $x->{value} = $LIB -> _sqrt($x->{value});
3150 75         251 return $x -> round(@r);
3151             }
3152              
3153             sub bpow {
3154             # (BINT or num_str, BINT or num_str) return BINT
3155             # compute power of two numbers -- stolen from Knuth Vol 2 pg 233
3156             # modifies first argument
3157              
3158             # set up parameters
3159 520 100 100 520 1 4338 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3160             ? (ref($_[0]), @_)
3161             : objectify(2, @_);
3162              
3163             ###########################################################################
3164             # Code for all classes that share the common interface.
3165             ###########################################################################
3166              
3167             # Don't modify constant (read-only) objects.
3168              
3169 520 50       2342 return $x if $x -> modify('bpow');
3170              
3171             # $x and/or $y is a NaN
3172 520 100 100     1798 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
3173              
3174             # $x and/or $y is a +/-Inf
3175 455 100       1690 if ($x -> is_inf("-")) {
    100          
    100          
    100          
3176 39 100       189 return $x -> bzero(@r) if $y -> is_negative();
3177 23 100       119 return $x -> bnan(@r) if $y -> is_zero();
3178 20 100       82 return $x -> round(@r) if $y -> is_odd();
3179 10         64 return $x -> bneg(@r);
3180             } elsif ($x -> is_inf("+")) {
3181 35 100       151 return $x -> bzero(@r) if $y -> is_negative();
3182 19 100       88 return $x -> bnan(@r) if $y -> is_zero();
3183 16         60 return $x -> round(@r);
3184             } elsif ($y -> is_inf("-")) {
3185 21 100       99 return $x -> bnan(@r) if $x -> is_one("-");
3186 18 100       80 return $x -> binf("+", @r) if $x -> is_zero();
3187 15 100       51 return $x -> bone(@r) if $x -> is_one("+");
3188 12         68 return $x -> bzero(@r);
3189             } elsif ($y -> is_inf("+")) {
3190 21 100       127 return $x -> bnan(@r) if $x -> is_one("-");
3191 18 100       85 return $x -> bzero(@r) if $x -> is_zero();
3192 15 100       48 return $x -> bone(@r) if $x -> is_one("+");
3193 12         48 return $x -> binf("+", @r);
3194             }
3195              
3196 339 100       1392 if ($x -> is_zero()) {
3197 26 100       64 return $x -> bone(@r) if $y -> is_zero();
3198 22 100       69 return $x -> binf(@r) if $y -> is_negative();
3199 11         41 return $x -> round(@r);
3200             }
3201              
3202 313 100       946 if ($x -> is_one("+")) {
3203 28         79 return $x -> round(@r);
3204             }
3205              
3206 285 100       808 if ($x -> is_one("-")) {
3207 31 100       103 return $x -> round(@r) if $y -> is_odd();
3208 14         74 return $x -> bneg(@r);
3209             }
3210              
3211             ###########################################################################
3212             # Code for things that aren't Math::BigInt
3213             ###########################################################################
3214              
3215 254 100       1000 return $x -> _upg() -> bpow($y, @r) if $class -> upgrade();
3216              
3217             # We don't support finite non-integers, so return zero. The reason for
3218             # returning zero, not NaN, is that all output is in the open interval
3219             # (0,1), and truncating that to integer gives zero.
3220              
3221 223 100 66     1761 if ($y->{sign} eq '-' || !$y -> isa(__PACKAGE__)) {
3222 36         144 return $x -> bzero(@r);
3223             }
3224              
3225 187         485 $r[3] = $y; # no push!
3226              
3227 187         1117 $x->{value} = $LIB -> _pow($x->{value}, $y->{value});
3228 187 100 100     839 $x->{sign} = $x -> is_negative() && $y -> is_odd() ? '-' : '+';
3229 187         1055 $x -> round(@r);
3230             }
3231              
3232             sub broot {
3233             # calculate $y'th root of $x
3234              
3235             # set up parameters
3236              
3237 177 100 66 177 1 3458 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3238             ? (ref($_[0]), @_) : objectify(2, @_);
3239              
3240 177 50       756 $y = $class -> new("2") unless defined $y; # default base
3241              
3242             # Don't modify constant (read-only) objects.
3243              
3244 177 50       833 return $x if $x -> modify('broot');
3245              
3246             # If called with "foreign" argument.
3247              
3248 177 50       973 unless ($y -> isa(__PACKAGE__)) {
3249 0 0       0 if ($y -> is_int()) {
3250 0         0 $y = $y -> as_int();
3251             } else {
3252 0 0       0 return $x -> _upg() -> broot($y, @r) if $class -> upgrade();
3253 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
3254             }
3255             }
3256              
3257             # NaN handling: $x ** 1/0, x or y NaN, or y inf/-inf or y == 0
3258             return $x -> bnan(@r) if ($x->{sign} !~ /^\+/ || $y -> is_zero() ||
3259 177 100 100     1771 $y->{sign} !~ /^\+$/);
      100        
3260              
3261             # Quick exit for trivial cases.
3262 102 100 100     343 return $x -> round(@r)
      100        
      100        
3263             if $x -> is_zero() || $x -> is_one() || $x -> is_inf() || $y -> is_one();
3264              
3265 90 100       371 return $x -> _upg() -> broot($y, @r) if $class -> upgrade();
3266              
3267 88         595 $x->{value} = $LIB->_root($x->{value}, $y->{value});
3268 88         390 $x -> round(@r);
3269             }
3270              
3271             sub bmuladd {
3272             # multiply two numbers and then add the third to the result
3273             # (BINT or num_str, BINT or num_str, BINT or num_str) return BINT
3274              
3275             # set up parameters
3276 177 50 33 177 1 3730 my ($class, $x, $y, $z, @r)
3277             = ref($_[0]) && ref($_[0]) eq ref($_[1]) && ref($_[1]) eq ref($_[2])
3278             ? (ref($_[0]), @_)
3279             : objectify(3, @_);
3280              
3281             # Don't modify constant (read-only) objects.
3282              
3283 177 50       642 return $x if $x -> modify('bmuladd');
3284              
3285             # At least one of x, y, and z is a NaN
3286              
3287 177 100 100     591 return $x -> bnan(@r) if ($x -> is_nan() ||
      100        
3288             $y -> is_nan() ||
3289             $z -> is_nan());
3290              
3291             # At least one of x, y, and z is an Inf
3292              
3293 153 100       446 if ($x -> is_inf("-")) {
    100          
    100          
    100          
    50          
3294              
3295 6 100       25 if ($y -> is_neg()) { # x = -inf, y < 0
    50          
3296 3 50       15 if ($z -> is_inf("-")) {
3297 0         0 return $x -> bnan(@r);
3298             } else {
3299 3         12 return $x -> binf("+", @r);
3300             }
3301             } elsif ($y -> is_zero()) { # x = -inf, y = 0
3302 0         0 return $x -> bnan(@r);
3303             } else { # x = -inf, y > 0
3304 3 50       24 if ($z->{sign} eq "+inf") {
3305 0         0 return $x -> bnan(@r);
3306             } else {
3307 3         13 return $x -> binf("-", @r);
3308             }
3309             }
3310              
3311             } elsif ($x->{sign} eq "+inf") {
3312              
3313 6 100       26 if ($y -> is_neg()) { # x = +inf, y < 0
    50          
3314 3 50       17 if ($z->{sign} eq "+inf") {
3315 0         0 return $x -> bnan(@r);
3316             } else {
3317 3         14 return $x -> binf("-", @r);
3318             }
3319             } elsif ($y -> is_zero()) { # x = +inf, y = 0
3320 0         0 return $x -> bnan(@r);
3321             } else { # x = +inf, y > 0
3322 3 50       12 if ($z -> is_inf("-")) {
3323 0         0 return $x -> bnan(@r);
3324             } else {
3325 3         12 return $x -> binf("+", @r);
3326             }
3327             }
3328              
3329             } elsif ($x -> is_neg()) {
3330              
3331 27 50       77 if ($y -> is_inf("-")) { # -inf < x < 0, y = -inf
    50          
3332 0 0       0 if ($z -> is_inf("-")) {
3333 0         0 return $x -> bnan(@r);
3334             } else {
3335 0         0 return $x -> binf("+", @r);
3336             }
3337             } elsif ($y->{sign} eq "+inf") { # -inf < x < 0, y = +inf
3338 0 0       0 if ($z->{sign} eq "+inf") {
3339 0         0 return $x -> bnan(@r);
3340             } else {
3341 0         0 return $x -> binf("-", @r);
3342             }
3343             } else { # -inf < x < 0, -inf < y < +inf
3344 27 50       73 if ($z -> is_inf("-")) {
    50          
3345 0         0 return $x -> binf("-", @r);
3346             } elsif ($z->{sign} eq "+inf") {
3347 0         0 return $x -> binf("+", @r);
3348             }
3349             }
3350              
3351             } elsif ($x -> is_zero()) {
3352              
3353 12 50       31 if ($y -> is_inf("-")) { # x = 0, y = -inf
    50          
3354 0         0 return $x -> bnan(@r);
3355             } elsif ($y->{sign} eq "+inf") { # x = 0, y = +inf
3356 0         0 return $x -> bnan(@r);
3357             } else { # x = 0, -inf < y < +inf
3358 12 50       30 if ($z -> is_inf("-")) {
    50          
3359 0         0 return $x -> binf("-", @r);
3360             } elsif ($z->{sign} eq "+inf") {
3361 0         0 return $x -> binf("+", @r);
3362             }
3363             }
3364              
3365             } elsif ($x -> is_pos()) {
3366              
3367 102 50       264 if ($y -> is_inf("-")) { # 0 < x < +inf, y = -inf
    50          
3368 0 0       0 if ($z->{sign} eq "+inf") {
3369 0         0 return $x -> bnan(@r);
3370             } else {
3371 0         0 return $x -> binf("-", @r);
3372             }
3373             } elsif ($y->{sign} eq "+inf") { # 0 < x < +inf, y = +inf
3374 0 0       0 if ($z -> is_inf("-")) {
3375 0         0 return $x -> bnan(@r);
3376             } else {
3377 0         0 return $x -> binf("+", @r);
3378             }
3379             } else { # 0 < x < +inf, -inf < y < +inf
3380 102 50       320 if ($z -> is_inf("-")) {
    50          
3381 0         0 return $x -> binf("-", @r);
3382             } elsif ($z->{sign} eq "+inf") {
3383 0         0 return $x -> binf("+", @r);
3384             }
3385             }
3386             }
3387              
3388             # If called with "foreign" arguments.
3389              
3390 141 50 33     1119 unless ($y -> isa(__PACKAGE__) && $z -> isa(__PACKAGE__)) {
3391 0 0 0     0 if ($y -> is_int() && $z -> is_int()) {
3392 0         0 $y = $y -> as_int();
3393 0         0 $z = $z -> as_int();
3394             } else {
3395 0 0       0 return $x -> _upg() -> bmuladd($y, $z, @r) if $class -> upgrade();
3396 0 0       0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()"
3397             unless $y -> isa(__PACKAGE__);
3398 0 0       0 croak "Can't handle a ", ref($z), " in ", (caller(0))[3], "()"
3399             unless $z -> isa(__PACKAGE__);
3400             }
3401             }
3402              
3403             # At this point, we know that x, y, and z are finite numbers
3404              
3405             # TODO: what if $y and $z have A or P set?
3406 141         286 $r[3] = $z; # no push here
3407              
3408 141         289 my $zs = $z->{sign};
3409 141         473 my $zv = $z->{value};
3410 141 50       522 $zv = $LIB -> _copy($zv) if refaddr($x) eq refaddr($z);
3411              
3412 141 100       441 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
3413 141         811 $x->{value} = $LIB->_mul($x->{value}, $y->{value}); # do actual math
3414 141 100       497 $x->{sign} = '+' if $LIB->_is_zero($x->{value}); # no -0
3415              
3416             ($x->{value}, $x->{sign})
3417 141         626 = $LIB -> _sadd($x->{value}, $x->{sign}, $zv, $zs);
3418 141         690 return $x -> round(@r);
3419             }
3420              
3421             sub bmodpow {
3422             # Modular exponentiation. Raises a very large number to a very large
3423             # exponent in a given very large modulus quickly, thanks to binary
3424             # exponentiation. Supports negative exponents.
3425 571 50 33 571 1 12628 my ($class, $num, $exp, $mod, @r)
3426             = ref($_[0]) && ref($_[0]) eq ref($_[1]) && ref($_[1]) eq ref($_[2])
3427             ? (ref($_[0]), @_)
3428             : objectify(3, @_);
3429              
3430             ###########################################################################
3431             # Code for all classes that share the common interface.
3432             ###########################################################################
3433              
3434             # Don't modify constant (read-only) objects.
3435              
3436 571 50       2314 return $num if $num -> modify('bmodpow');
3437              
3438             # Check for valid input. All operands must be finite, and the modulus must
3439             # be non-zero.
3440              
3441 571 100 100     1800 return $num -> bnan(@r) if (!$num -> is_finite() || # NaN, -inf, +inf
      100        
3442             !$exp -> is_finite() || # NaN, -inf, +inf
3443             !$mod -> is_finite()); # NaN, -inf, +inf
3444              
3445             ###########################################################################
3446             # Code for things that aren't Math::BigInt
3447             ###########################################################################
3448              
3449             # If called with "foreign" arguments.
3450              
3451 508 50 33     3473 unless ($exp -> isa(__PACKAGE__) && $mod -> isa(__PACKAGE__)) {
3452 0 0 0     0 if ($exp -> is_int() && $mod -> is_int()) {
3453 0         0 $exp = $exp -> as_int();
3454 0         0 $mod = $mod -> as_int();
3455             } else {
3456 0 0       0 return $num -> _upg() -> bmodpow($exp, $mod, @r) if $class -> upgrade();
3457 0 0       0 croak "Can't handle a ", ref($exp), " in ", (caller(0))[3], "()"
3458             unless $exp -> isa(__PACKAGE__);
3459 0 0       0 croak "Can't handle a ", ref($mod), " in ", (caller(0))[3], "()"
3460             unless $mod -> isa(__PACKAGE__);
3461             }
3462             }
3463              
3464             # When the exponent 'e' is negative, use the following relation, which is
3465             # based on finding the multiplicative inverse 'd' of 'b' modulo 'm':
3466             #
3467             # b^(-e) (mod m) = d^e (mod m) where b*d = 1 (mod m)
3468             #
3469             # Return NaN if no modular multiplicative inverse exists.
3470              
3471 508 100       1469 if ($exp->{sign} eq '-') {
3472 143         545 $num -> bmodinv($mod);
3473 143 100       473 return $num -> bnan(@r) if $num -> is_nan();
3474             }
3475              
3476             # Modulo zero. See documentation for Math::BigInt's bmod() method.
3477              
3478 465 100       1540 if ($mod -> is_zero()) {
3479 3 50       12 if ($num -> is_zero()) {
3480 0         0 return $num -> bnan(@r);
3481             } else {
3482 3         14 return $num -> round(@r);
3483             }
3484             }
3485              
3486             ###########################################################################
3487             # Code for Math::BigInt objects
3488             ###########################################################################
3489              
3490             # Compute 'a (mod m)', ignoring the signs on 'a' and 'm'. If the resulting
3491             # value is zero, the output is also zero, regardless of the signs on 'a'
3492             # and 'm'.
3493              
3494 462         2177 my $value = $LIB->_modpow($num->{value}, $exp->{value}, $mod->{value});
3495 462         1107 my $sign = '+';
3496              
3497             # If the resulting value is non-zero, we have four special cases, depending
3498             # on the signs on 'a' and 'm'.
3499              
3500 462 100       1412 unless ($LIB->_is_zero($value)) {
3501              
3502             # There is a negative sign on 'a' (= $num**$exp) only if the number we
3503             # are exponentiating ($num) is negative and the exponent ($exp) is odd.
3504              
3505 239 100 100     1032 if ($num->{sign} eq '-' && $exp -> is_odd()) {
3506              
3507             # When both the number 'a' and the modulus 'm' have a negative
3508             # sign, use this relation:
3509             #
3510             # -a (mod -m) = -(a (mod m))
3511              
3512 21 50       70 if ($mod->{sign} eq '-') {
3513 0         0 $sign = '-';
3514             }
3515              
3516             # When only the number 'a' has a negative sign, use this relation:
3517             #
3518             # -a (mod m) = m - (a (mod m))
3519              
3520             else {
3521             # Use copy of $mod since _sub() modifies the first argument.
3522 21         74 my $mod = $LIB->_copy($mod->{value});
3523 21         93 $value = $LIB->_sub($mod, $value);
3524 21         51 $sign = '+';
3525             }
3526              
3527             } else {
3528              
3529             # When only the modulus 'm' has a negative sign, use this relation:
3530             #
3531             # a (mod -m) = (a (mod m)) - m
3532             # = -(m - (a (mod m)))
3533              
3534 218 100       656 if ($mod->{sign} eq '-') {
3535             # Use copy of $mod since _sub() modifies the first argument.
3536 7         33 my $mod = $LIB->_copy($mod->{value});
3537 7         32 $value = $LIB->_sub($mod, $value);
3538 7         36 $sign = '-';
3539             }
3540              
3541             # When neither the number 'a' nor the modulus 'm' have a negative
3542             # sign, directly return the already computed value.
3543             #
3544             # (a (mod m))
3545              
3546             }
3547              
3548             }
3549              
3550 462         1075 $num->{value} = $value;
3551 462         938 $num->{sign} = $sign;
3552              
3553 462         1389 return $num -> round(@r);
3554             }
3555              
3556             sub bmodinv {
3557             # Return modular multiplicative inverse:
3558             #
3559             # z is the modular inverse of x (mod y) if and only if
3560             #
3561             # x*z ≡ 1 (mod y)
3562             #
3563             # If the modulus y is larger than one, x and z are relative primes (i.e.,
3564             # their greatest common divisor is one).
3565             #
3566             # If no modular multiplicative inverse exists, NaN is returned.
3567              
3568             # set up parameters
3569 313 50 33 313 1 3947 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3570             ? (ref($_[0]), @_)
3571             : objectify(2, @_);
3572              
3573             ###########################################################################
3574             # Code for all classes that share the common interface.
3575             ###########################################################################
3576              
3577             # Don't modify constant (read-only) objects.
3578              
3579 313 50       1137 return $x if $x -> modify('bmodinv');
3580              
3581             # Return NaN if one or both arguments is +inf, -inf, or nan.
3582              
3583 313 100 100     893 return $x -> bnan(@r) if !$y -> is_finite() || !$x -> is_finite();
3584              
3585             # Return NaN if $y is zero; 1 % 0 makes no sense.
3586              
3587 264 50       873 return $x -> bnan(@r) if $y -> is_zero();
3588              
3589             ###########################################################################
3590             # Code for things that aren't Math::BigInt
3591             ###########################################################################
3592              
3593             # If called with "foreign" arguments.
3594              
3595 264 50       1142 unless ($y -> isa(__PACKAGE__)) {
3596 0 0       0 if ($y -> is_int()) {
3597 0         0 $y = $y -> as_int();
3598             } else {
3599 0 0       0 return $x -> _upg() -> bmodinv($y, @r) if $class -> upgrade();
3600 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
3601             }
3602             }
3603              
3604             ###########################################################################
3605             # Code for Math::BigInt objects
3606             ###########################################################################
3607              
3608             # Return 0 in the trivial case. $x % 1 or $x % -1 is zero for all finite
3609             # integers $x.
3610              
3611 264 100 66     832 return $x -> bzero(@r) if $y -> is_one('+') || $y -> is_one('-');
3612              
3613             # Return NaN if $x = 0, or $x modulo $y is zero. The only valid case when
3614             # $x = 0 is when $y = 1 or $y = -1, but that was covered above.
3615             #
3616             # Note that computing $x modulo $y here affects the value we'll feed to
3617             # $LIB->_modinv() below when $x and $y have opposite signs. E.g., if $x =
3618             # 5 and $y = 7, those two values are fed to _modinv(), but if $x = -5 and
3619             # $y = 7, the values fed to _modinv() are $x = 2 (= -5 % 7) and $y = 7.
3620             # The value if $x is affected only when $x and $y have opposite signs.
3621              
3622 201         991 $x -> bfmod($y);
3623 201 100       644 return $x -> bnan(@r) if $x -> is_zero();
3624              
3625             # Compute the modular multiplicative inverse of the absolute values. We'll
3626             # correct for the signs of $x and $y later. Return NaN if no GCD is found.
3627              
3628 165         942 ($x->{value}, $x->{sign}) = $LIB->_modinv($x->{value}, $y->{value});
3629 165 100       719 return $x -> bnan(@r) if !defined($x->{value});
3630              
3631             # Library inconsistency workaround: _modinv() in Math::BigInt::GMP versions
3632             # <= 1.32 return undef rather than a "+" for the sign.
3633              
3634 140 50       348 $x->{sign} = '+' unless defined $x->{sign};
3635              
3636             # When one or both arguments are negative, we have the following
3637             # relations. If x and y are positive:
3638             #
3639             # modinv(-x, -y) = -modinv(x, y)
3640             # modinv(-x, y) = y - modinv(x, y) = -modinv(x, y) (mod y)
3641             # modinv( x, -y) = modinv(x, y) - y = modinv(x, y) (mod -y)
3642              
3643             # We must swap the sign of the result if the original $x is negative.
3644             # However, we must compensate for ignoring the signs when computing the
3645             # inverse modulo. The net effect is that we must swap the sign of the
3646             # result if $y is negative.
3647              
3648 140 100       402 $x -> bneg() if $y->{sign} eq '-';
3649              
3650             # Compute $x modulo $y again after correcting the sign.
3651              
3652 140 100       3014 $x -> bmod($y) if $x->{sign} ne $y->{sign};
3653              
3654 140         404 $x -> round(@r);
3655             }
3656              
3657             sub blog {
3658             # Return the logarithm of the operand. If a second operand is defined, that
3659             # value is used as the base, otherwise the base is assumed to be Euler's
3660             # constant.
3661              
3662 199     199 1 3710 my ($class, $x, $base, @r);
3663              
3664             # Only objectify the base if it is defined, since an undefined base, as in
3665             # $x->blog() or $x->blog(undef) signals that the base is Euler's number =
3666             # 2.718281828...
3667              
3668 199 50 33     625 if (!ref($_[0]) && $_[0] =~ /^[a-z]\w*(?:::\w+)*$/i) {
3669             # E.g., Math::BigInt->blog(256, 2)
3670 0 0       0 ($class, $x, $base, @r) =
3671             defined $_[2] ? objectify(2, @_) : objectify(1, @_);
3672             } else {
3673             # E.g., $x->blog(2) or the deprecated Math::BigInt::blog(256, 2)
3674 199 100       860 ($class, $x, $base, @r) =
3675             defined $_[1] ? objectify(2, @_) : objectify(1, @_);
3676             }
3677              
3678             # Don't modify constant (read-only) objects.
3679              
3680 199 50       2105 return $x if $x->modify('blog');
3681              
3682             # Handle all exception cases and all trivial cases. I have used Wolfram
3683             # Alpha (http://www.wolframalpha.com) as the reference for these cases.
3684              
3685 199 100       617 return $x -> bnan(@r) if $x -> is_nan();
3686              
3687 190 100       536 if (defined $base) {
3688 160 50 33     856 $base = $class -> new($base)
3689             unless defined(blessed($base)) && $base -> isa(__PACKAGE__);
3690 160 100 100     395 if ($base -> is_nan() || $base -> is_one()) {
    100 100        
    100          
3691 12         60 return $x -> bnan(@r);
3692             } elsif ($base -> is_inf() || $base -> is_zero()) {
3693 36 100 100     96 return $x -> bnan(@r) if $x -> is_inf() || $x -> is_zero();
3694 15         49 return $x -> bzero(@r);
3695             } elsif ($base -> is_negative()) { # -inf < base < 0
3696 12 100       36 return $x -> bzero(@r) if $x -> is_one(); # x = 1
3697 9 50       45 return $x -> bone('+', @r) if $x == $base; # x = base
3698             # we can't handle these cases, so upgrade, if we can
3699 9 50       45 return $x -> _upg() -> blog($base, @r) if $class -> upgrade();
3700 9         46 return $x -> bnan(@r);
3701             }
3702 100 100       453 return $x -> bone(@r) if $x == $base; # 0 < base && 0 < x < inf
3703             }
3704              
3705             # We now know that the base is either undefined or >= 2 and finite.
3706              
3707 127 100       342 if ($x -> is_inf()) { # x = +/-inf
    100          
    100          
    100          
3708 15         45 return $x -> binf('+', @r);
3709             } elsif ($x -> is_neg()) { # -inf < x < 0
3710 6 50       33 return $x -> _upg() -> blog($base, @r) if $class -> upgrade();
3711 6         27 return $x -> bnan(@r);
3712             } elsif ($x -> is_one()) { # x = 1
3713 9         47 return $x -> bzero(@r);
3714             } elsif ($x -> is_zero()) { # x = 0
3715 6         24 return $x -> binf('-', @r);
3716             }
3717              
3718             # At this point we are done handling all exception cases and trivial cases.
3719              
3720 91 100       373 return $x -> _upg() -> blog($base, @r) if $class -> upgrade();
3721              
3722             # fix for bug #24969:
3723             # the default base is e (Euler's number) which is not an integer
3724 89 100       227 if (!defined $base) {
3725 15         141 require Math::BigFloat;
3726              
3727             # disable upgrading and downgrading
3728              
3729 15         70 my $upg = Math::BigFloat -> upgrade();
3730 15         49 my $dng = Math::BigFloat -> downgrade();
3731 15         48 Math::BigFloat -> upgrade(undef);
3732 15         41 Math::BigFloat -> downgrade(undef);
3733              
3734 15         94 my $u = Math::BigFloat -> new($x) -> blog() -> as_int();
3735              
3736             # reset upgrading and downgrading
3737              
3738 15         134 Math::BigFloat -> upgrade($upg);
3739 15         51 Math::BigFloat -> downgrade($dng);
3740              
3741             # modify $x in place
3742              
3743 15         69 $x->{value} = $u->{value};
3744 15         42 $x->{sign} = $u->{sign};
3745              
3746 15         64 return $x -> round(@r);
3747             }
3748              
3749 74         307 my ($rc) = $LIB -> _log_int($x->{value}, $base->{value});
3750 74 50       231 return $x -> bnan(@r) unless defined $rc; # not possible to take log?
3751 74         172 $x->{value} = $rc;
3752 74         244 $x -> round(@r);
3753             }
3754              
3755             sub bexp {
3756             # Calculate e ** $x (Euler's number to the power of X), truncated to
3757             # an integer value.
3758 15 50   15 1 197 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3759              
3760             ###########################################################################
3761             # Code for all classes that share the common interface.
3762             ###########################################################################
3763              
3764             # Don't modify constant (read-only) objects.
3765              
3766 15 50       73 return $x if $x -> modify('bexp');
3767              
3768             # inf, -inf, NaN, <0 => NaN
3769 15 100       91 return $x -> bnan(@r) if $x -> is_nan();
3770 12 50       49 return $x -> bone(@r) if $x -> is_zero();
3771 12 100       45 return $x -> round(@r) if $x -> is_inf("+");
3772 9 50       43 return $x -> bzero(@r) if $x -> is_inf("-");
3773              
3774             ###########################################################################
3775             # Output might be finite, non-integer, so upgrade.
3776             ###########################################################################
3777              
3778 9 50       55 return $x -> _upg() -> bexp(@r) if $class -> upgrade();
3779              
3780             ###########################################################################
3781             # Code for things that aren't Math::BigInt
3782             ###########################################################################
3783              
3784 9 50       65 unless ($x -> isa(__PACKAGE__)) {
3785 0         0 croak "Can't handle a ", ref($x), " in ", (caller(0))[3], "()";
3786             }
3787              
3788             ###########################################################################
3789             # Code for Math::BigInt objects
3790             ###########################################################################
3791              
3792 9         5419 require Math::BigFloat;
3793 9         104 my $tmp = Math::BigFloat -> bexp($x) -> bint() -> round(@r) -> as_int();
3794 9         76 $x->{value} = $tmp->{value};
3795 9         35 return $x -> round(@r);
3796             }
3797              
3798             sub bilog2 {
3799 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3800              
3801             # Don't modify constant (read-only) objects.
3802              
3803 0 0       0 return $x if $x -> modify('bilog2');
3804              
3805 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
3806 0 0       0 return $x -> binf("+", @r) if $x -> is_inf("+");
3807 0 0       0 return $x -> binf("-", @r) if $x -> is_zero();
3808              
3809 0 0       0 if ($x -> is_neg()) {
3810 0 0       0 return $x -> _upg() -> bilog2(@r) if $class -> upgrade();
3811 0         0 return $x -> bnan(@r);
3812             }
3813              
3814 0         0 $x -> {value} = $LIB -> _ilog2($x -> {value});
3815 0         0 return $x -> round(@r);
3816             }
3817              
3818             sub bilog10 {
3819 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3820              
3821             # Don't modify constant (read-only) objects.
3822              
3823 0 0       0 return $x if $x -> modify('bilog10');
3824              
3825 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
3826 0 0       0 return $x -> binf("+", @r) if $x -> is_inf("+");
3827 0 0       0 return $x -> binf("-", @r) if $x -> is_zero();
3828              
3829 0 0       0 if ($x -> is_neg()) {
3830 0 0       0 return $x -> _upg() -> bilog10(@r) if $class -> upgrade();
3831 0         0 return $x -> bnan(@r);
3832             }
3833              
3834 0         0 $x -> {value} = $LIB -> _ilog10($x -> {value});
3835 0         0 return $x -> round(@r);
3836             }
3837              
3838             sub bclog2 {
3839 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3840              
3841             # Don't modify constant (read-only) objects.
3842              
3843 0 0       0 return $x if $x -> modify('bclog2');
3844              
3845 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
3846 0 0       0 return $x -> binf("+", @r) if $x -> is_inf("+");
3847 0 0       0 return $x -> binf("-", @r) if $x -> is_zero();
3848              
3849 0 0       0 if ($x -> is_neg()) {
3850 0 0       0 return $x -> _upg() -> bclog2(@r) if $class -> upgrade();
3851 0         0 return $x -> bnan(@r);
3852             }
3853              
3854 0         0 $x -> {value} = $LIB -> _clog2($x -> {value});
3855 0         0 return $x -> round(@r);
3856             }
3857              
3858             sub bclog10 {
3859 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
3860              
3861             # Don't modify constant (read-only) objects.
3862              
3863 0 0       0 return $x if $x -> modify('bclog10');
3864              
3865 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
3866 0 0       0 return $x -> binf("+", @r) if $x -> is_inf("+");
3867 0 0       0 return $x -> binf("-", @r) if $x -> is_zero();
3868              
3869 0 0       0 if ($x -> is_neg()) {
3870 0 0       0 return $x -> _upg() -> bclog10(@r) if $class -> upgrade();
3871 0         0 return $x -> bnan(@r);
3872             }
3873              
3874 0         0 $x -> {value} = $LIB -> _clog10($x -> {value});
3875 0         0 return $x -> round(@r);
3876             }
3877              
3878             sub bnok {
3879             # Calculate n over k (binomial coefficient or "choose" function) as
3880             # integer.
3881              
3882             # Set up parameters.
3883 93 50 33 93 1 1324 my ($class, $n, $k, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3884             ? (ref($_[0]), @_)
3885             : objectify(2, @_);
3886              
3887 93 50       218 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
3888              
3889             # Don't modify constant (read-only) objects.
3890              
3891 93 50       340 return $n if $n -> modify('bnok');
3892              
3893             # If called with "foreign" arguments.
3894              
3895 93 50       416 unless ($k -> isa(__PACKAGE__)) {
3896 0 0       0 if ($k -> is_int()) {
3897 0         0 $k = $k -> as_int();
3898             } else {
3899 0 0       0 return $n -> _upg() -> bnok($k, @r) if $class -> upgrade();
3900 0         0 croak "Can't handle a ", ref($k), " in ", (caller(0))[3], "()";
3901             }
3902             }
3903              
3904             # All cases where at least one argument is NaN.
3905              
3906 93 100 100     252 return $n -> bnan(@r) if $n -> is_nan() || $k -> is_nan();
3907              
3908             # All cases where at least one argument is +/-inf.
3909              
3910 84 100       242 if ($n -> is_inf()) {
    50          
3911 7 50       24 if ($k -> is_inf()) { # bnok(+/-inf,+/-inf)
    50          
    50          
3912 0         0 return $n -> bnan(@r);
3913             } elsif ($k -> is_neg()) { # bnok(+/-inf,k), k < 0
3914 0         0 return $n -> bzero(@r);
3915             } elsif ($k -> is_zero()) { # bnok(+/-inf,k), k = 0
3916 0         0 return $n -> bone(@r);
3917             } else {
3918 7 50       24 if ($n -> is_inf("+", @r)) { # bnok(+inf,k), 0 < k < +inf
3919 7         34 return $n -> binf("+");
3920             } else { # bnok(-inf,k), k > 0
3921 0 0       0 my $sign = $k -> is_even() ? "+" : "-";
3922 0         0 return $n -> binf($sign, @r);
3923             }
3924             }
3925             }
3926              
3927             elsif ($k -> is_inf()) { # bnok(n,+/-inf), -inf <= n <= inf
3928 0         0 return $n -> bnan(@r);
3929             }
3930              
3931             # At this point, both n and k are real numbers.
3932              
3933 77         149 my $sign = 1;
3934              
3935 77 50       299 if ($n >= 0) {
3936 77 100 100     248 if ($k < 0 || $k > $n) {
3937 21         102 return $n -> bzero(@r);
3938             }
3939             } else {
3940              
3941 0 0       0 if ($k >= 0) {
    0          
3942              
3943             # n < 0 and k >= 0: bnok(n,k) = (-1)^k * bnok(-n+k-1,k)
3944              
3945 0         0 $sign = (-1) ** $k;
3946 0         0 $n -> bneg() -> badd($k) -> bdec();
3947              
3948             } elsif ($k <= $n) {
3949              
3950             # n < 0 and k <= n: bnok(n,k) = (-1)^(n-k) * bnok(-k-1,n-k)
3951              
3952 0         0 $sign = (-1) ** ($n - $k);
3953 0         0 my $x0 = $n -> copy();
3954 0         0 $n -> bone() -> badd($k) -> bneg();
3955 0         0 $k = $k -> copy();
3956 0         0 $k -> bneg() -> badd($x0);
3957              
3958             } else {
3959              
3960             # n < 0 and n < k < 0:
3961              
3962 0         0 return $n -> bzero(@r);
3963             }
3964             }
3965              
3966             # Some backends, e.g., Math::BigInt::GMP, can't handle the case when k is
3967             # very large, so if k > n/2, or, equivalently, 2*k > n, perform range
3968             # reduction by computing nok(n, k) as nok(n, n-k).
3969              
3970 56         145 my $k_val = $k->{value};
3971 56         233 my $two_k = $LIB -> _mul($LIB -> _two(), $k_val);
3972 56 100       189 if ($LIB -> _acmp($two_k, $n->{value}) > 0) {
3973 28         115 $k_val = $LIB -> _sub($LIB -> _copy($n->{value}), $k_val);
3974             }
3975              
3976 56         254 $n->{value} = $LIB -> _nok($n->{value}, $k_val);
3977 56 50       135 $n -> bneg() if $sign == -1;
3978 56         170 $n -> round(@r);
3979             }
3980              
3981             sub bperm {
3982             # Calculate permutations: n! / (n - k)!
3983              
3984             # Set up parameters.
3985 0 0 0 0 1 0 my ($class, $n, $k, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
3986             ? (ref($_[0]), @_)
3987             : objectify(2, @_);
3988              
3989 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
3990              
3991             # Don't modify constant (read-only) objects.
3992              
3993 0 0       0 return $n if $n -> modify('bnok');
3994              
3995             # If called with "foreign" arguments.
3996              
3997 0 0       0 unless ($k -> isa(__PACKAGE__)) {
3998 0 0       0 if ($k -> is_int()) {
3999 0         0 $k = $k -> as_int();
4000             } else {
4001 0 0       0 return $n -> _upg() -> bperm($k, @r) if $class -> upgrade();
4002 0         0 croak "Can't handle a ", ref($k), " in ", (caller(0))[3], "()";
4003             }
4004             }
4005              
4006             # Special cases.
4007              
4008 0 0 0     0 return $n -> bnan(@r) if $n -> is_nan() || $k -> is_nan();
4009 0 0 0     0 return $n -> bnan(@r) unless $n >= $k && $k >= 0;
4010 0 0       0 return $n -> bone("+", @r) if $k -> is_zero();
4011              
4012 0 0       0 if ($n -> is_inf()) {
4013 0 0       0 if ($k -> is_inf()) {
4014 0         0 return $n -> bnan(@r);
4015             } else {
4016 0         0 return $n -> binf("+", @r);
4017             }
4018             }
4019              
4020             # Should this code be moved into the backend library? XXX
4021              
4022             # $factor is $n
4023 0         0 my $factor = $LIB -> _copy($n->{value});
4024              
4025             # $limit is $n - $k + 1
4026 0         0 my $limit = $LIB -> _copy($n->{value});
4027 0         0 $limit = $LIB -> _sub($limit, $k->{value});
4028 0         0 $limit = $LIB -> _inc($limit);
4029              
4030 0         0 while ($LIB -> _acmp($factor, $limit) > 0) {
4031 0         0 $LIB -> _dec($factor);
4032 0         0 $LIB -> _mul($n->{value}, $factor);
4033             }
4034              
4035 0         0 $n -> round(@r);
4036             }
4037              
4038             sub bhyperop {
4039 0     0 1 0 my ($class, $a, $n, $b, @r) = objectify(3, @_);
4040              
4041             # Don't modify constant (read-only) objects.
4042              
4043 0 0       0 return $a if $a -> modify('bhyperop');
4044              
4045 0         0 my $tmp = $a -> hyperop($n, $b);
4046 0         0 $a -> {value} = $tmp -> {value};
4047 0         0 return $a -> round(@r);
4048             }
4049              
4050             sub hyperop {
4051 0     0 1 0 my ($class, $a, $n, $b, @r) = objectify(3, @_);
4052              
4053 0 0       0 croak("a must be non-negative") if $a < 0;
4054 0 0       0 croak("n must be non-negative") if $n < 0;
4055 0 0       0 croak("b must be non-negative") if $b < 0;
4056              
4057             # The following is a non-recursive implementation of the hyperoperator,
4058             # with special cases handled for speed.
4059              
4060 0         0 my @stack = ($a, $n, $b);
4061 0         0 while (@stack > 1) {
4062 0         0 my ($a, $n, $b) = splice @stack, -3;
4063              
4064             # Special cases for $b
4065              
4066 0 0 0     0 if ($b == 2 && $a == 2) {
4067 0 0       0 push @stack, $n == 0 ? Math::BigInt -> new("3")
4068             : Math::BigInt -> new("4");
4069 0         0 next;
4070             }
4071              
4072 0 0       0 if ($b == 1) {
4073 0 0       0 if ($n == 0) {
4074 0         0 push @stack, Math::BigInt -> new("2");
4075 0         0 next;
4076             }
4077 0 0       0 if ($n == 1) {
4078 0         0 push @stack, $a + 1;
4079 0         0 next;
4080             }
4081 0         0 push @stack, $a;
4082 0         0 next;
4083             }
4084              
4085 0 0       0 if ($b == 0) {
4086 0 0       0 if ($n == 1) {
4087 0         0 push @stack, $a;
4088 0         0 next;
4089             }
4090 0 0       0 if ($n == 2) {
4091 0         0 push @stack, Math::BigInt -> bzero();
4092 0         0 next;
4093             }
4094 0         0 push @stack, Math::BigInt -> bone();
4095 0         0 next;
4096             }
4097              
4098             # Special cases for $a
4099              
4100 0 0       0 if ($a == 0) {
4101 0 0       0 if ($n == 0) {
4102 0         0 push @stack, $b + 1;
4103 0         0 next;
4104             }
4105 0 0       0 if ($n == 1) {
4106 0         0 push @stack, $b;
4107 0         0 next;
4108             }
4109 0 0       0 if ($n == 2) {
4110 0         0 push @stack, Math::BigInt -> bzero();
4111 0         0 next;
4112             }
4113 0 0       0 if ($n == 3) {
4114 0 0       0 push @stack, $b == 0 ? Math::BigInt -> bone()
4115             : Math::BigInt -> bzero();
4116 0         0 next;
4117             }
4118 0 0       0 push @stack, $b -> is_odd() ? Math::BigInt -> bzero()
4119             : Math::BigInt -> bone();
4120 0         0 next;
4121             }
4122              
4123 0 0       0 if ($a == 1) {
4124 0 0 0     0 if ($n == 0 || $n == 1) {
4125 0         0 push @stack, $b + 1;
4126 0         0 next;
4127             }
4128 0 0       0 if ($n == 2) {
4129 0         0 push @stack, $b;
4130 0         0 next;
4131             }
4132 0         0 push @stack, Math::BigInt -> bone();
4133 0         0 next;
4134             }
4135              
4136             # Special cases for $n
4137              
4138 0 0       0 if ($n == 4) { # tetration
4139 0 0       0 if ($b == 0) {
4140 0         0 push @stack, Math::BigInt -> bone();
4141 0         0 next;
4142             }
4143 0         0 my $y = $a;
4144 0         0 $y = $a ** $y for 2 .. $b;
4145 0         0 push @stack, $y;
4146 0         0 next;
4147             }
4148              
4149 0 0       0 if ($n == 3) { # exponentiation
4150 0         0 push @stack, $a ** $b;
4151 0         0 next;
4152             }
4153              
4154 0 0       0 if ($n == 2) { # multiplication
4155 0         0 push @stack, $a * $b;
4156 0         0 next;
4157             }
4158              
4159 0 0       0 if ($n == 1) { # addition
4160 0         0 push @stack, $a + $b;
4161 0         0 next;
4162             }
4163              
4164 0 0       0 if ($n == 0) { # succession
4165 0         0 push @stack, $b + 1;
4166 0         0 next;
4167             }
4168              
4169 0         0 push @stack, $a, $n - 1, $a, $n, $b - 1;
4170             }
4171              
4172 0         0 $a = pop @stack;
4173 0         0 return $a -> round(@r);
4174             }
4175              
4176             sub buparrow {
4177 0     0 1 0 my ($class, $a, $n, $b, @r) = objectify(3, @_);
4178              
4179             # Don't modify constant (read-only) objects.
4180              
4181 0 0       0 return $a if $a -> modify('buparrow');
4182              
4183 0         0 $a -> bhyperop($n + 2, $b, @r);
4184             }
4185              
4186             sub uparrow {
4187 0     0 1 0 my ($class, $a, $n, $b, @r) = objectify(3, @_);
4188 0         0 $a -> hyperop($n + 2, $b, @r);
4189             }
4190              
4191             sub backermann {
4192 0     0 1 0 my $m = shift;
4193              
4194             # Don't modify constant (read-only) objects.
4195              
4196 0 0       0 return $m if $m -> modify('backermann');
4197              
4198 0         0 my $y = $m -> ackermann(@_);
4199 0         0 $m -> {value} = $y -> {value};
4200 0         0 return $m;
4201             }
4202              
4203             sub ackermann {
4204             # Ackermann's function ackermann(m, n)
4205             #
4206             # The following is a simple, recursive implementation of the ackermann
4207             # function, just to show the idea. Such implementations cause "Deep
4208             # recursion on subroutine ..." warnings, so we use a faster, non-recursive
4209             # algorithm below with @_ as a stack.
4210             #
4211             # sub ackermann {
4212             # my ($m, $n) = @_;
4213             # return $n + 1 if $m == 0;
4214             # return ackermann($m - 1, 1) if $m > 0 && $n == 0;
4215             # return ackermann($m - 1, ackermann($m, $n - 1) if $m > 0 && $n > 0;
4216             # }
4217              
4218 0     0 1 0 my ($m, $n) = @_;
4219 0         0 my $class = ref $m;
4220 0 0       0 croak("m must be non-negative") if $m < 0;
4221 0 0       0 croak("n must be non-negative") if $n < 0;
4222              
4223 0         0 my $two = $class -> new("2");
4224 0         0 my $three = $class -> new("3");
4225 0         0 my $thirteen = $class -> new("13");
4226              
4227 0         0 $n = pop;
4228 0 0       0 $n = $class -> new($n) unless ref($n);
4229 0         0 while (@_) {
4230 0         0 my $m = pop;
4231 0 0       0 if ($m > $three) {
    0          
    0          
    0          
4232 0         0 push @_, (--$m) x $n;
4233 0         0 while (--$m >= $three) {
4234 0         0 push @_, $m;
4235             }
4236 0         0 $n = $thirteen;
4237             } elsif ($m == $three) {
4238 0         0 $n = $class -> bone() -> blsft($n + $three) -> bsub($three);
4239             } elsif ($m == $two) {
4240 0         0 $n -> bmul($two) -> badd($three);
4241             } elsif ($m >= 0) {
4242 0         0 $n -> badd($m) -> binc();
4243             } else {
4244 0         0 die "negative m!";
4245             }
4246             }
4247 0         0 $n;
4248             }
4249              
4250             sub bsin {
4251 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4252              
4253             # Don't modify constant (read-only) objects.
4254              
4255 0 0       0 return $x if $x -> modify('bsin');
4256              
4257             # Trivial cases.
4258              
4259 0 0       0 return $x -> bzero(@r) if $x -> is_zero();
4260 0 0 0     0 return $x -> bnan(@r) if $x -> is_inf() || $x -> is_nan();
4261              
4262 0         0 my $upg = $class -> upgrade();
4263 0 0       0 if ($upg) {
4264 0         0 my $xtmp = $upg -> bsin($x, @r);
4265 0 0       0 if ($xtmp -> is_int()) {
4266 0         0 $xtmp = $xtmp -> as_int();
4267 0         0 %$x = %$xtmp;
4268             } else {
4269 0         0 %$x = %$xtmp;
4270 0         0 bless $x, $upg;
4271             }
4272 0         0 return $x;
4273             }
4274              
4275             # When x is an integer ≠ 0, sin(x) truncated to an integer is always zero.
4276              
4277 0         0 $x -> bzero(@r);
4278             }
4279              
4280             sub bcos {
4281 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4282              
4283             # Don't modify constant (read-only) objects.
4284              
4285 0 0       0 return $x if $x -> modify('bcos');
4286              
4287             # Trivial cases.
4288              
4289 0 0       0 return $x -> bone(@r) if $x -> is_zero();
4290 0 0 0     0 return $x -> bnan(@r) if $x -> is_inf() || $x -> is_nan();
4291              
4292 0         0 my $upg = $class -> upgrade();
4293 0 0       0 if ($upg) {
4294 0         0 my $xtmp = $upg -> bcos($x, @r);
4295 0 0       0 if ($xtmp -> is_int()) {
4296 0         0 $xtmp = $xtmp -> as_int();
4297 0         0 %$x = %$xtmp;
4298             } else {
4299 0         0 %$x = %$xtmp;
4300 0         0 bless $x, $upg;
4301             }
4302 0         0 return $x;
4303             }
4304              
4305             # When x is a non-zero integer, cos(x) truncated to an integer is always
4306             # zero.
4307              
4308 0         0 $x -> bzero(@r);
4309             }
4310              
4311             sub batan {
4312             # Calculate arctan(x) to N digits. Unless upgrading is in effect, returns
4313             # the result truncated to an integer.
4314 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4315              
4316             # Don't modify constant (read-only) objects.
4317              
4318 0 0       0 return $x if $x -> modify('batan');
4319              
4320 0 0       0 return $x -> bnan(@r) if $x -> is_nan();
4321 0 0       0 return $x -> bzero(@r) if $x -> is_zero();
4322              
4323 0 0       0 return $x -> _upg() -> batan(@r) if $class -> upgrade();
4324              
4325 0 0       0 return $x -> bone("+", @r) if $x -> bgt("1");
4326 0 0       0 return $x -> bone("-", @r) if $x -> blt("-1");
4327              
4328 0         0 $x -> bzero(@r);
4329             }
4330              
4331             sub batan2 {
4332             # calculate arcus tangens of ($y/$x)
4333              
4334 84 50 33 84 1 1731 my ($class, $y, $x, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
4335             ? (ref($_[0]), @_) : objectify(2, @_);
4336              
4337             # Don't modify constant (read-only) objects.
4338              
4339 84 50       431 return $y if $y -> modify('batan2');
4340              
4341             # If called with "foreign" arguments.
4342              
4343 84 50       460 unless ($y -> isa(__PACKAGE__)) {
4344 0 0       0 if ($y -> is_int()) {
4345 0         0 $y = $y -> as_int();
4346             } else {
4347 0 0       0 return $y -> _upg() -> batan2($y, @r) if $class -> upgrade();
4348 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
4349             }
4350             }
4351              
4352 84 100 100     330 return $y -> bnan() if $y -> is_nan() || $x -> is_nan();
4353              
4354             # Y X
4355             # != 0 -inf result is +- pi
4356 75 100 100     258 if ($x -> is_inf() || $y -> is_inf()) {
4357 30 100       72 if ($y -> is_inf()) {
4358 18 100       395 if ($x -> is_inf("-")) {
    100          
4359             # calculate 3 pi/4 => 2.3.. => 2
4360 6         72 $y -> bone(substr($y->{sign}, 0, 1));
4361 6         47 $y -> bmul($class -> new(2));
4362             } elsif ($x -> is_inf("+")) {
4363             # calculate pi/4 => 0.7 => 0
4364 6         64 $y -> bzero();
4365             } else {
4366             # calculate pi/2 => 1.5 => 1
4367 6         42 $y -> bone(substr($y->{sign}, 0, 1));
4368             }
4369             } else {
4370 12 100       32 if ($x -> is_inf("+")) {
4371             # calculate pi/4 => 0.7 => 0
4372 3         22 $y -> bzero();
4373             } else {
4374             # PI => 3.1415.. => 3
4375 9         62 $y -> bone(substr($y->{sign}, 0, 1));
4376 9         37 $y -> bmul($class -> new(3));
4377             }
4378             }
4379 30         514 return $y;
4380             }
4381              
4382             # Temporarily disable downgrading in Math::BigFloat.
4383              
4384 45         183 my $dng = Math::BigFloat -> downgrade();
4385 45         171 Math::BigFloat -> downgrade(undef);
4386              
4387 45         241 my $yflt = $y -> as_float();
4388 45         145 my $xflt = $x -> as_float();
4389 45         1797 my $yint = $yflt -> batan2($xflt, @r) -> as_int();
4390              
4391 45         221 $y->{value} = $yint->{value};
4392 45         172 $y->{sign} = $yint->{sign};
4393              
4394             # Restore downgrading.
4395              
4396 45         150 Math::BigFloat -> downgrade($dng);
4397 45         138 $y -> round(@r);
4398             }
4399              
4400             sub bfac {
4401             # (BINT or num_str, BINT or num_str) return BINT
4402             # compute factorial number from $x, modify $x in place
4403 89 50   89 1 1228 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4404              
4405             # Don't modify constant (read-only) objects.
4406              
4407 89 50       438 return $x if $x -> modify('bfac');
4408              
4409 89 100 100     348 return $x -> bnan(@r) if $x -> is_nan() || $x -> is_inf("-");;
4410 83 100       278 return $x -> binf("+", @r) if $x -> is_inf("+");
4411 80 100       299 return $x -> bnan(@r) if $x -> is_neg();
4412 77 100 100     297 return $x -> bone(@r) if $x -> is_zero() || $x -> is_one();
4413              
4414 69         326 $x->{value} = $LIB->_fac($x->{value});
4415 69         241 $x -> round(@r);
4416             }
4417              
4418             sub bdfac {
4419             # compute double factorial, modify $x in place
4420 54 50   54 1 1015 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4421              
4422             # Don't modify constant (read-only) objects.
4423              
4424 54 50       287 return $x if $x -> modify('bdfac');
4425              
4426 54 100 100     222 return $x -> bnan(@r) if $x -> is_nan() || $x -> is_inf("-");
4427 48 100       184 return $x -> binf("+", @r) if $x -> is_inf("+");
4428 45 100       236 return $x -> bnan(@r) if $x <= -2;
4429 42 100       148 return $x -> bone(@r) if $x <= 1;
4430              
4431 33 50       316 croak("bdfac() requires a newer version of the $LIB library.")
4432             unless $LIB -> can('_dfac');
4433              
4434 33         194 $x->{value} = $LIB->_dfac($x->{value});
4435 33         137 $x -> round(@r);
4436             }
4437              
4438             sub btfac {
4439             # compute triple factorial, modify $x in place
4440 57 50   57 1 1000 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4441              
4442             # Don't modify constant (read-only) objects.
4443              
4444 57 50       272 return $x if $x -> modify('btfac');
4445              
4446 57 100       219 return $x -> bnan(@r) if $x -> is_nan();
4447 54 100       231 return $x -> binf("+", @r) if $x -> is_inf("+");
4448              
4449 51         170 my $k = $class -> new("3");
4450 51 100       352 return $x -> bnan(@r) if $x <= -$k;
4451              
4452 45         357 my $one = $class -> bone();
4453 45 100       126 return $x -> bone(@r) if $x <= $one;
4454              
4455 33         119 my $f = $x -> copy();
4456 33         190 while ($f -> bsub($k) > $one) {
4457 45         166 $x -> bmul($f);
4458             }
4459 33         137 $x -> round(@r);
4460             }
4461              
4462             sub bmfac {
4463             # compute multi-factorial
4464              
4465 270 50 33 270 1 6229 my ($class, $x, $k, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
4466             ? (ref($_[0]), @_) : objectify(2, @_);
4467              
4468             # Don't modify constant (read-only) objects.
4469              
4470 270 50       1459 return $x if $x -> modify('bmfac');
4471              
4472 270 100       1104 return $x -> bnan(@r) if $x -> is_nan();
4473 255 100       800 return $x -> bnan(@r) if $k -> is_nan();
4474 252 100       974 return $x -> binf("+", @r) if $x -> is_inf("+");
4475              
4476             # If called with "foreign" arguments.
4477              
4478 237 50       1276 unless ($k -> isa(__PACKAGE__)) {
4479 0 0       0 if ($k -> is_int()) {
4480 0         0 $k = $k -> as_int();
4481             } else {
4482 0 0       0 return $x -> _upg() -> bmfac($k, @r) if $class -> upgrade();
4483 0         0 croak "Can't handle a ", ref($k), " in ", (caller(0))[3], "()";
4484             }
4485             }
4486              
4487 237 100 100     1127 return $x -> bnan(@r) if $k < 1 || $x <= -$k;
4488              
4489 198         1524 my $one = $class -> bone();
4490 198 100       669 return $x -> bone(@r) if $x <= $one;
4491              
4492 138         511 my $f = $x -> copy();
4493 138         743 while ($f -> bsub($k) > $one) {
4494 213         784 $x -> bmul($f);
4495             }
4496 138         480 $x -> round(@r);
4497             }
4498              
4499             sub bfib {
4500             # compute Fibonacci number(s)
4501 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4502              
4503 0 0       0 croak("bfib() requires a newer version of the $LIB library.")
4504             unless $LIB -> can('_fib');
4505              
4506             # Don't modify constant (read-only) objects.
4507              
4508 0 0       0 return $x if $x -> modify('bfib');
4509              
4510             # List context.
4511              
4512 0 0       0 if (wantarray) {
4513 0 0       0 croak("bfib() can't return an infinitely long list of numbers")
4514             if $x -> is_inf();
4515              
4516 0 0 0     0 return if $x -> is_nan() || !$x -> is_int();
4517              
4518             # The following places a limit on how large $x can be. Should this
4519             # limit be removed? XXX
4520              
4521 0         0 my $n = $x -> numify();
4522              
4523 0         0 my @y;
4524             {
4525 0         0 $y[0] = $x -> copy() -> babs();
  0         0  
4526 0         0 $y[0]{value} = $LIB -> _zero();
4527 0 0       0 last if $n == 0;
4528              
4529 0         0 $y[1] = $y[0] -> copy();
4530 0         0 $y[1]{value} = $LIB -> _one();
4531 0 0       0 last if $n == 1;
4532              
4533 0         0 for (my $i = 2 ; $i <= abs($n) ; $i++) {
4534 0         0 $y[$i] = $y[$i - 1] -> copy();
4535             $y[$i]{value} = $LIB -> _add($LIB -> _copy($y[$i - 1]{value}),
4536 0         0 $y[$i - 2]{value});
4537             }
4538              
4539             # If negative, insert sign as appropriate.
4540              
4541 0 0       0 if ($x -> is_neg()) {
4542 0         0 for (my $i = 2 ; $i <= $#y ; $i += 2) {
4543 0         0 $y[$i]{sign} = '-';
4544             }
4545             }
4546              
4547             # The last element in the array is the invocand.
4548              
4549 0         0 $x->{value} = $y[-1]{value};
4550 0         0 $x->{sign} = $y[-1]{sign};
4551 0         0 $y[-1] = $x;
4552             }
4553              
4554 0         0 @y = map { $_ -> round(@r) } @y;
  0         0  
4555 0         0 return @y;
4556             }
4557              
4558             # Scalar context.
4559              
4560             else {
4561 0 0       0 return $x if $x -> is_inf('+');
4562 0 0 0     0 return $x -> bnan() if $x -> is_nan() || $x -> is_inf('-');
4563              
4564 0 0 0     0 $x->{sign} = $x -> is_neg() && $x -> is_even() ? '-' : '+';
4565 0         0 $x->{value} = $LIB -> _fib($x->{value});
4566 0         0 return $x -> round(@r);
4567             }
4568             }
4569              
4570             sub blucas {
4571             # compute Lucas number(s)
4572 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
4573              
4574 0 0       0 croak("blucas() requires a newer version of the $LIB library.")
4575             unless $LIB -> can('_lucas');
4576              
4577             # Don't modify constant (read-only) objects.
4578              
4579 0 0       0 return $x if $x -> modify('blucas');
4580              
4581             # List context.
4582              
4583 0 0       0 if (wantarray) {
4584 0 0       0 return if $x -> is_nan();
4585 0 0       0 croak("blucas() can't return an infinitely long list of numbers")
4586             if $x -> is_inf();
4587              
4588             # The following places a limit on how large $x can be. Should this
4589             # limit be removed? XXX
4590              
4591 0         0 my $n = $x -> numify();
4592              
4593 0         0 my @y;
4594             {
4595 0         0 $y[0] = $x -> copy() -> babs();
  0         0  
4596 0         0 $y[0]{value} = $LIB -> _two();
4597 0 0       0 last if $n == 0;
4598              
4599 0         0 $y[1] = $y[0] -> copy();
4600 0         0 $y[1]{value} = $LIB -> _one();
4601 0 0       0 last if $n == 1;
4602              
4603 0         0 for (my $i = 2 ; $i <= abs($n) ; $i++) {
4604 0         0 $y[$i] = $y[$i - 1] -> copy();
4605             $y[$i]{value} = $LIB -> _add($LIB -> _copy($y[$i - 1]{value}),
4606 0         0 $y[$i - 2]{value});
4607             }
4608              
4609             # If negative, insert sign as appropriate.
4610              
4611 0 0       0 if ($x -> is_neg()) {
4612 0         0 for (my $i = 2 ; $i <= $#y ; $i += 2) {
4613 0         0 $y[$i]{sign} = '-';
4614             }
4615             }
4616              
4617             # The last element in the array is the invocand.
4618              
4619 0         0 $x->{value} = $y[-1]{value};
4620 0         0 $x->{sign} = $y[-1]{sign};
4621 0         0 $y[-1] = $x;
4622             }
4623              
4624 0         0 @y = map { $_ -> round(@r) } @y;
  0         0  
4625 0         0 return @y;
4626             }
4627              
4628             # Scalar context.
4629              
4630             else {
4631 0 0       0 return $x if $x -> is_inf('+');
4632 0 0 0     0 return $x -> bnan() if $x -> is_nan() || $x -> is_inf('-');
4633              
4634 0 0 0     0 $x->{sign} = $x -> is_neg() && $x -> is_even() ? '-' : '+';
4635 0         0 $x->{value} = $LIB -> _lucas($x->{value});
4636 0         0 return $x -> round(@r);
4637             }
4638             }
4639              
4640             sub blsft {
4641             # (BINT or num_str, BINT or num_str) return BINT
4642             # compute $x << $y, base $n
4643              
4644 62     62 1 681 my ($class, $x, $y, $b, @r);
4645              
4646             # Objectify the base only when it is defined, since an undefined base, as
4647             # in $x->blsft(3) or $x->blog(3, undef) means use the default base 2.
4648              
4649 62 100 66     307 if (!ref($_[0]) && $_[0] =~ /^[A-Za-z]|::/) {
4650             # E.g., Math::BigInt->blog(256, 5, 2)
4651 12 50       72 ($class, $x, $y, $b, @r) =
4652             defined $_[3] ? objectify(3, @_) : objectify(2, @_);
4653             } else {
4654             # E.g., Math::BigInt::blog(256, 5, 2) or $x->blog(5, 2)
4655 50 100       291 ($class, $x, $y, $b, @r) =
4656             defined $_[2] ? objectify(3, @_) : objectify(2, @_);
4657             }
4658              
4659             # Don't modify constant (read-only) objects.
4660              
4661 62 50       302 return $x if $x -> modify('blsft');
4662              
4663             # The default base is 2.
4664              
4665 62 100       374 $b = 2 unless defined $b;
4666 62 100       306 $b = $class -> new($b) unless defined(blessed($b));
4667              
4668             # If called with "foreign" arguments.
4669              
4670 62 50 33     480 unless ($y -> isa(__PACKAGE__) && $b -> isa(__PACKAGE__)) {
4671 0 0 0     0 if ($y -> is_int() && $b -> is_int()) {
4672 0         0 $y = $y -> as_int();
4673 0         0 $b = $b -> as_int();
4674             } else {
4675 0 0       0 return $x -> _upg() -> blsft($y, $b, @r) if $class -> upgrade();
4676 0 0       0 croak "Can't handle a ", ref($x), " in ", (caller(0))[3], "()"
4677             unless $y -> isa(__PACKAGE__);
4678 0 0       0 croak "Can't handle a ", ref($b), " in ", (caller(0))[3], "()"
4679             unless $b -> isa(__PACKAGE__);
4680             }
4681             }
4682              
4683             # Handle NaN cases.
4684              
4685 62 50 33     188 return $x -> bnan(@r)
      33        
4686             if $x -> is_nan() || $y -> is_nan() || $b -> is_nan();
4687              
4688             # blsft($x, -$y, $b) = brsft($x, $y, $b)
4689              
4690 62 100       193 return $x -> brsft($y -> copy() -> bneg(), $b, @r) if $y -> is_neg();
4691              
4692             # Now handle all cases where at least one operand is ±Inf or the result
4693             # will be ±Inf or NaN.
4694              
4695 58 50       165 if ($y -> is_inf("+")) {
4696 0 0       0 if ($b -> is_one("-")) {
    0          
    0          
4697 0         0 return $x -> bnan(@r);
4698             } elsif ($b -> is_one("+")) {
4699 0         0 return $x -> round(@r);
4700             } elsif ($b -> is_zero()) {
4701 0 0       0 return $x -> bnan(@r) if $x -> is_inf();
4702 0         0 return $x -> bzero(@r);
4703             } else {
4704 0 0       0 return $x -> binf("-", @r) if $x -> is_negative();
4705 0 0       0 return $x -> binf("+", @r) if $x -> is_positive();
4706 0         0 return $x -> bnan(@r);
4707             }
4708             }
4709              
4710 58 50       145 if ($b -> is_inf()) {
4711 0 0 0     0 return $x -> bnan(@r) if $x -> is_zero() || $y -> is_zero();
4712 0 0       0 if ($b -> is_inf("-")) {
4713 0 0 0     0 return $x -> binf("+", @r)
      0        
      0        
4714             if ($x -> is_negative() && $y -> is_odd() ||
4715             $x -> is_positive() && $y -> is_even());
4716 0         0 return $x -> binf("-", @r);
4717             } else {
4718 0 0       0 return $x -> binf("-", @r) if $x -> is_negative();
4719 0         0 return $x -> binf("+", @r);
4720             }
4721             }
4722              
4723 58 50       186 if ($b -> is_zero()) {
4724 0 0       0 return $x -> round(@r) if $y -> is_zero();
4725 0 0       0 return $x -> bnan(@r) if $x -> is_inf();
4726 0         0 return $x -> bzero(@r);
4727             }
4728              
4729 58 50       125 if ($x -> is_inf()) {
4730 0 0       0 if ($b -> is_negative()) {
4731 0 0       0 if ($x -> is_inf("-")) {
4732 0 0       0 if ($y -> is_even()) {
4733 0         0 return $x -> round(@r);
4734             } else {
4735 0         0 return $x -> binf("+", @r);
4736             }
4737             } else {
4738 0 0       0 if ($y -> is_even()) {
4739 0         0 return $x -> round(@r);
4740             } else {
4741 0         0 return $x -> binf("-", @r);
4742             }
4743             }
4744             } else {
4745 0         0 return $x -> round(@r);
4746             }
4747             }
4748              
4749             # At this point, we know that both the input and the output is finite.
4750             # Handle some trivial cases.
4751              
4752 58 50 66     130 return $x -> round(@r) if $x -> is_zero() || $y -> is_zero()
      66        
      33        
      66        
4753             || $b -> is_one("+")
4754             || $b -> is_one("-") && $y -> is_even();
4755              
4756 50 50 33     136 return $x -> bneg(@r) if $b -> is_one("-") && $y -> is_odd();
4757              
4758             # While some of the libraries support an arbitrarily large base, not all of
4759             # them do, so rather than returning an incorrect result in those cases,
4760             # disallow bases that don't work with all libraries.
4761              
4762 50         100 my $uintmax = ~0;
4763 50 50       207 if ($x -> bcmp($uintmax) > 0) {
4764 0         0 $x -> bmul($b -> bpow($y));
4765             } else {
4766 50         108 my $neg = 0;
4767 50 50       162 if ($b -> is_negative()) {
4768 0 0       0 $neg = 1 if $y -> is_odd();
4769 0         0 $b -> babs();
4770             }
4771 50         185 $b = $b -> numify();
4772 50         321 $x -> {value} = $LIB -> _lsft($x -> {value}, $y -> {value}, $b);
4773 50 50       144 $x -> {sign} =~ tr/+-/-+/ if $neg;
4774             }
4775 50         176 $x -> round(@r);
4776             }
4777              
4778             sub brsft {
4779             # (BINT or num_str, BINT or num_str) return BINT
4780             # compute $x >> $y, base $n
4781              
4782 134     134 1 1939 my ($class, $x, $y, $b, @r);
4783              
4784             # Objectify the base only when it is defined, since an undefined base, as
4785             # in $x->blsft(3) or $x->blog(3, undef) means use the default base 2.
4786              
4787 134 100 66     725 if (!ref($_[0]) && $_[0] =~ /^[A-Za-z]|::/) {
4788             # E.g., Math::BigInt->blog(256, 5, 2)
4789 12 50       67 ($class, $x, $y, $b, @r) =
4790             defined $_[3] ? objectify(3, @_) : objectify(2, @_);
4791             } else {
4792             # E.g., Math::BigInt::blog(256, 5, 2) or $x -> blog(5, 2)
4793 122 100       649 ($class, $x, $y, $b, @r) =
4794             defined $_[2] ? objectify(3, @_) : objectify(2, @_);
4795             }
4796              
4797             # Don't modify constant (read-only) objects.
4798              
4799 134 50       636 return $x if $x -> modify('brsft');
4800              
4801             # The default base is 2.
4802              
4803 134 100       360 $b = 2 unless defined $b;
4804 134 100       480 $b = $class -> new($b) unless defined(blessed($b));
4805              
4806             # If called with "foreign" arguments.
4807              
4808 134 50 33     965 unless ($y -> isa(__PACKAGE__) && $b -> isa(__PACKAGE__)) {
4809 0 0 0     0 if ($y -> is_int() && $b -> is_int()) {
4810 0         0 $y = $y -> as_int();
4811 0         0 $b = $b -> as_int();
4812             } else {
4813 0 0       0 return $x -> _upg() -> brsft($y, $b, @r) if $class -> upgrade();
4814 0 0       0 croak "Can't handle a ", ref($x), " in ", (caller(0))[3], "()"
4815             unless $y -> isa(__PACKAGE__);
4816 0 0       0 croak "Can't handle a ", ref($b), " in ", (caller(0))[3], "()"
4817             unless $b -> isa(__PACKAGE__);
4818             }
4819             }
4820              
4821             # Handle NaN cases.
4822              
4823 134 50 33     423 return $x -> bnan(@r)
      33        
4824             if $x -> is_nan() || $y -> is_nan() || $b -> is_nan();
4825              
4826             # brsft($x, -$y, $b) = blsft($x, $y, $b)
4827              
4828 134 100       448 return $x -> blsft($y -> copy() -> bneg(), $b, @r) if $y -> is_neg();
4829              
4830             # Now handle all cases where at least one operand is ±Inf or the result
4831             # will be ±Inf or NaN.
4832              
4833 130 50       371 if ($b -> is_inf()) {
4834 0 0 0     0 return $x -> bnan(@r) if $x -> is_inf() || $y -> is_zero();
4835 0 0       0 if ($b -> is_inf("+")) {
4836 0 0       0 if ($x -> is_negative()) {
4837 0         0 return $x -> bone("-", @r);
4838             } else {
4839 0         0 return $x -> bzero(@r);
4840             }
4841             } else {
4842 0 0       0 if ($x -> is_negative()) {
    0          
4843 0 0       0 return $y -> is_odd() ? $x -> bzero(@r)
4844             : $x -> bone("-", @r);
4845             } elsif ($x -> is_positive()) {
4846 0 0       0 return $y -> is_odd() ? $x -> bone("-", @r)
4847             : $x -> bzero(@r);
4848             } else {
4849 0         0 return $x -> bzero(@r);
4850             }
4851             }
4852             }
4853              
4854 130 50       442 if ($b -> is_zero()) {
4855 0 0       0 return $x -> round(@r) if $y -> is_zero();
4856 0 0       0 return $x -> bnan(@r) if $x -> is_zero();
4857 0 0       0 return $x -> is_negative() ? $x -> binf("-", @r)
4858             : $x -> binf("+", @r);
4859             }
4860              
4861 130 50       291 if ($y -> is_inf("+")) {
4862 0 0       0 if ($b -> is_one("-")) {
    0          
4863 0         0 return $x -> bnan(@r);
4864             } elsif ($b -> is_one("+")) {
4865 0         0 return $x -> round(@r);
4866             } else {
4867 0 0       0 return $x -> bnan(@r) if $x -> is_inf();
4868 0 0       0 return $x -> is_negative() ? $x -> bone("-", @r)
4869             : $x -> bzero(@r);
4870             }
4871             }
4872              
4873 130 50       529 if ($x -> is_inf()) {
4874 0 0       0 if ($b -> is_negative()) {
4875 0 0       0 if ($x -> is_inf("-")) {
4876 0 0       0 if ($y -> is_even()) {
4877 0         0 return $x -> round(@r);
4878             } else {
4879 0         0 return $x -> binf("+", @r);
4880             }
4881             } else {
4882 0 0       0 if ($y -> is_even()) {
4883 0         0 return $x -> round(@r);
4884             } else {
4885 0         0 return $x -> binf("-", @r);
4886             }
4887             }
4888             } else {
4889 0         0 return $x -> round(@r);
4890             }
4891             }
4892              
4893             # At this point, we know that both the input and the output is finite.
4894             # Handle some trivial cases.
4895              
4896 130 50 66     472 return $x -> round(@r) if $x -> is_zero() || $y -> is_zero()
      66        
      33        
      66        
4897             || $b -> is_one("+")
4898             || $b -> is_one("-") && $y -> is_even();
4899              
4900 122 50 33     331 return $x -> bneg(@r) if $b -> is_one("-") && $y -> is_odd();
4901              
4902             # We know that $y is positive. Shifting right by a positive amount might
4903             # lead to a non-integer result.
4904              
4905 122 100       423 return $x -> _upg() -> brsft($y, $b, @r) if $class -> upgrade();
4906              
4907             # This only works for negative numbers when shifting in base 2.
4908 111 100 66     302 if ($x -> is_neg() && $b -> bcmp("2") == 0) {
4909 57 100       200 return $x -> round(@r) if $x -> is_one('-'); # -1 => -1
4910             # Although this is O(N*N) in Math::BigInt::Calc->_as_bin(), it is O(N)
4911             # in Pari et al., but perhaps there is a better emulation for two's
4912             # complement shift ... if $y != 1, we must simulate it by doing:
4913             # convert to bin, flip all bits, shift, and be done
4914 54         247 $x -> binc(); # -3 => -2
4915 54         268 my $bin = $x -> to_bin(); # convert to string
4916 54         279 $bin =~ s/^-//; # strip leading minus
4917 54         123 $bin =~ tr/10/01/; # flip bits
4918 54         99 my $nbits = CORE::length($bin);
4919 54 100       260 return $x -> bone("-", @r) if $y >= $nbits;
4920 51         297 $bin = substr $bin, 0, $nbits - $y; # keep most significant bits
4921 51         198 $bin = '1' . $bin; # prepend one dummy '1'
4922 51         133 $bin =~ tr/10/01/; # flip bits back
4923 51         195 my $res = $class -> from_bin($bin); # convert back from string
4924 51         253 $res -> binc(); # remember to increment
4925 51         168 $x -> {value} = $res -> {value}; # take over value
4926 51         179 return $x -> round(@r);
4927             }
4928              
4929             # While some of the libraries support an arbitrarily large base, not all of
4930             # them do, so rather than returning an incorrect result in those cases, use
4931             # division.
4932              
4933 54         130 my $uintmax = ~0;
4934 54 50 33     184 if ($x -> bcmp($uintmax) > 0 || $x -> is_neg() || $b -> is_negative()) {
      33        
4935 0         0 $x -> bdiv($b -> bpow($y));
4936             } else {
4937 54         284 $b = $b -> numify();
4938 54         383 $x -> {value} = $LIB -> _rsft($x -> {value}, $y -> {value}, $b);
4939             }
4940              
4941 54         205 return $x -> round(@r);
4942             }
4943              
4944             ###############################################################################
4945             # Bitwise methods
4946             ###############################################################################
4947              
4948             # Bitwise left shift.
4949              
4950             sub bblsft {
4951             # We don't call objectify(), because the bitwise methods should not
4952             # upgrade, even when upgrading is enabled.
4953              
4954 35     35 1 84 my ($class, $x, $y, @r);
4955              
4956             # $x -> bblsft($y)
4957              
4958 35 100       127 if (ref($_[0])) {
4959 27         88 ($class, $x, $y, @r) = (ref($_[0]), @_);
4960 27 50 33     222 $y = $y -> as_int()
      33        
4961             if ref($y) && !$y -> isa(__PACKAGE__) && $y -> can('as_int');
4962 27 50       95 $y = $class -> new(int($y)) unless ref($y);
4963             }
4964              
4965             # $class -> bblsft($x, $y)
4966              
4967             else {
4968 8         20 ($class, $x, $y, @r) = @_;
4969 8         26 for ($x, $y) {
4970 16 50 33     81 $_ = $_ -> as_int()
      33        
4971             if ref($_) && !$_ -> isa(__PACKAGE__) && $_ -> can('as_int');
4972 16 50       52 $_ = $class -> new(int($_)) unless ref($_);
4973             }
4974             }
4975              
4976             # Don't modify constant (read-only) objects.
4977              
4978 35 50       176 return $x if $x -> modify('bblsft');
4979              
4980 35 100 66     118 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
4981              
4982             # bblsft($x, -$y) = bbrsft($x, $y)
4983              
4984 31 100       802 return $x -> bbrsft($y -> copy() -> bneg()) if $y -> is_neg();
4985              
4986             # Shifting infinitely far to the left.
4987              
4988 27 50       83 if ($y -> is_inf("+")) {
4989 0 0       0 return $x -> binf("+", @r) if $x -> is_pos();
4990 0 0       0 return $x -> binf("-", @r) if $x -> is_neg();
4991 0         0 return $x -> bnan(@r);
4992             }
4993              
4994             # These cases change nothing.
4995              
4996 27 50 33     126 return $x -> round(@r) if $x -> is_zero() || $x -> is_inf() ||
      33        
4997             $y -> is_zero();
4998              
4999 27         167 $x -> {value} = $LIB -> _lsft($x -> {value}, $y -> {value}, 2);
5000 27         101 $x -> round(@r);
5001             }
5002              
5003             # Bitwise right shift.
5004              
5005             sub bbrsft {
5006             # We don't call objectify(), because the bitwise methods should not
5007             # upgrade, even when upgrading is enabled.
5008              
5009 35     35 1 75 my ($class, $x, $y, @r);
5010              
5011             # $x -> bblsft($y)
5012              
5013 35 100       118 if (ref($_[0])) {
5014 27         77 ($class, $x, $y, @r) = (ref($_[0]), @_);
5015 27 50 33     192 $y = $y -> as_int()
      33        
5016             if ref($y) && !$y -> isa(__PACKAGE__) && $y -> can('as_int');
5017 27 50       88 $y = $class -> new(int($y)) unless ref($y);
5018             }
5019              
5020             # $class -> bblsft($x, $y)
5021              
5022             else {
5023 8         20 ($class, $x, $y, @r) = @_;
5024 8         26 for ($x, $y) {
5025 16 50 33     68 $_ = $_ -> as_int()
      33        
5026             if ref($_) && !$_ -> isa(__PACKAGE__) && $_ -> can('as_int');
5027 16 50       54 $_ = $class -> new(int($_)) unless ref($_);
5028             }
5029             }
5030              
5031             # Don't modify constant (read-only) objects.
5032              
5033 35 50       125 return $x if $x -> modify('bbrsft');
5034              
5035 35 100 66     104 return $x -> bnan(@r) if $x -> is_nan() || $y -> is_nan();
5036              
5037             # bbrsft($x, -$y) = bblsft($x, $y)
5038              
5039 31 100       96 return $x -> bblsft($y -> copy() -> bneg()) if $y -> is_neg();
5040              
5041             # Shifting infinitely far to the right.
5042              
5043 27 50       286 if ($y -> is_inf("+")) {
5044 0 0       0 return $x -> bnan(@r) if $x -> is_inf();
5045 0 0       0 return $x -> bone("-", @r) if $x -> is_neg();
5046 0         0 return $x -> bzero(@r);
5047             }
5048              
5049             # These cases change nothing.
5050              
5051 27 50 33     92 return $x -> round(@r) if $x -> is_zero() || $x -> is_inf() ||
      33        
5052             $y -> is_zero();
5053              
5054             # At this point, $x is either positive or negative, not zero.
5055              
5056 27 50       94 if ($x -> is_pos()) {
5057 27         162 $x -> {value} = $LIB -> _rsft($x -> {value}, $y -> {value}, 2);
5058             } else {
5059 0         0 my $n = $x -> {value};
5060 0         0 my $d = $LIB -> _pow($LIB -> _new("2"), $y -> {value});
5061 0         0 my ($p, $q) = $LIB -> _div($n, $d);
5062 0 0       0 $p = $LIB -> _inc($p) unless $LIB -> _is_zero($q);
5063 0         0 $x -> {value} = $p;
5064             }
5065              
5066 27         115 $x -> round(@r);
5067             }
5068              
5069             sub band {
5070             #(BINT or num_str, BINT or num_str) return BINT
5071             # compute x & y
5072              
5073 464 100 66 464 1 3037 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
5074             ? (ref($_[0]), @_) : objectify(2, @_);
5075              
5076             # Don't modify constant (read-only) objects.
5077              
5078 464 50       1538 return $x if $x -> modify('band');
5079              
5080             # If called with "foreign" arguments.
5081              
5082 464 100       1789 unless ($y -> isa(__PACKAGE__)) {
5083 1 50       4 if ($y -> is_int()) {
5084 0         0 $y = $y -> as_int();
5085             } else {
5086 1 50       2 return $x -> _upg() -> band($y, @r) if $class -> upgrade();
5087 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
5088             }
5089             }
5090              
5091 463         830 $r[3] = $y; # no push!
5092              
5093             # If $x and/or $y is Inf or NaN, return NaN.
5094              
5095 463 100 100     1221 return $x -> bnan(@r) if !$x -> is_finite() || !$y -> is_finite();
5096              
5097 451 100 100     1738 if ($x->{sign} eq '+' && $y->{sign} eq '+') {
5098 418         1992 $x->{value} = $LIB->_and($x->{value}, $y->{value});
5099             } else {
5100             ($x->{value}, $x->{sign}) = $LIB->_sand($x->{value}, $x->{sign},
5101 33         170 $y->{value}, $y->{sign});
5102             }
5103              
5104 451         2103 return $x -> round(@r);
5105             }
5106              
5107             sub bior {
5108             #(BINT or num_str, BINT or num_str) return BINT
5109             # compute x | y
5110              
5111 525 100 66 525 1 3388 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
5112             ? (ref($_[0]), @_) : objectify(2, @_);
5113              
5114             # Don't modify constant (read-only) objects.
5115              
5116 525 50       1710 return $x if $x -> modify('bior');
5117              
5118             # If called with "foreign" arguments.
5119              
5120 525 100       2028 unless ($y -> isa(__PACKAGE__)) {
5121 1 50       8 if ($y -> is_int()) {
5122 0         0 $y = $y -> as_int();
5123             } else {
5124 1 50       5 return $x -> _upg() -> bior($y, @r) if $class -> upgrade();
5125 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
5126             }
5127             }
5128              
5129 524         1003 $r[3] = $y; # no push!
5130              
5131             # If $x and/or $y is Inf or NaN, return NaN.
5132              
5133 524 100 100     1314 return $x -> bnan() if (!$x -> is_finite() || !$y -> is_finite());
5134              
5135 512 100 100     2046 if ($x->{sign} eq '+' && $y->{sign} eq '+') {
5136 477         2073 $x->{value} = $LIB->_or($x->{value}, $y->{value});
5137             } else {
5138             ($x->{value}, $x->{sign}) = $LIB->_sor($x->{value}, $x->{sign},
5139 35         257 $y->{value}, $y->{sign});
5140             }
5141 512         2352 return $x -> round(@r);
5142             }
5143              
5144             sub bxor {
5145             #(BINT or num_str, BINT or num_str) return BINT
5146             # compute x ^ y
5147              
5148 535 100 66 535 1 3812 my ($class, $x, $y, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
5149             ? (ref($_[0]), @_) : objectify(2, @_);
5150              
5151             # Don't modify constant (read-only) objects.
5152              
5153 535 50       1842 return $x if $x -> modify('bxor');
5154              
5155             # If called with "foreign" arguments.
5156              
5157 535 100       2244 unless ($y -> isa(__PACKAGE__)) {
5158 1 50       6 if ($y -> is_int()) {
5159 0         0 $y = $y -> as_int();
5160             } else {
5161 1 50       5 return $x -> _upg() -> bxor($y, @r) if $class -> upgrade();
5162 0         0 croak "Can't handle a ", ref($y), " in ", (caller(0))[3], "()";
5163             }
5164             }
5165              
5166 534         996 $r[3] = $y; # no push!
5167              
5168             # If $x and/or $y is Inf or NaN, return NaN.
5169              
5170 534 100 100     1574 return $x -> bnan(@r) if !$x -> is_finite() || !$y -> is_finite();
5171              
5172 522 100 100     2181 if ($x->{sign} eq '+' && $y->{sign} eq '+') {
5173 482         2313 $x->{value} = $LIB->_xor($x->{value}, $y->{value});
5174             } else {
5175             ($x->{value}, $x->{sign}) = $LIB->_sxor($x->{value}, $x->{sign},
5176 40         270 $y->{value}, $y->{sign});
5177             }
5178 522         2417 return $x -> round(@r);
5179             }
5180              
5181             sub bnot {
5182             # (num_str or BINT) return BINT
5183             # represent ~x as twos-complement number
5184 39 50   39 1 465 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5185              
5186             # Don't modify constant (read-only) objects.
5187              
5188 39 50       196 return $x if $x -> modify('bnot');
5189              
5190 39         168 $x -> binc() -> bneg(@r);
5191             }
5192              
5193             ###############################################################################
5194             # Rounding methods
5195             ###############################################################################
5196              
5197             sub round {
5198             # Round $self according to given parameters, or given second argument's
5199             # parameters or global defaults
5200 90005 50   90005 1 333102 my ($class, $self, @args) = ref($_[0]) ? (ref($_[0]), @_)
5201             : objectify(1, @_);
5202              
5203             # These signal no rounding:
5204             #
5205             # $x->round(undef)
5206             # $x->round(undef, undef, ...)
5207             #
5208             # The "@args <= 3" is necessary because the final set of parameters that
5209             # will be used for rounding depend on the "extra arguments", if any.
5210              
5211 90005 100 100     525232 if (@args == 1 && !defined($args[0]) ||
      100        
      100        
      100        
      100        
5212             @args >= 2 && @args <= 3 && !defined($args[0]) && !defined($args[1]))
5213             {
5214 70         179 $self->{accuracy} = undef;
5215 70         167 $self->{precision} = undef;
5216 70         259 return $self;
5217             }
5218              
5219 89935         238592 my ($a, $p, $r) = splice @args, 0, 3;
5220              
5221             # $a accuracy, if given by caller
5222             # $p precision, if given by caller
5223             # $r round_mode, if given by caller
5224             # @args all 'other' arguments (0 for unary, 1 for binary ops)
5225              
5226 89935 100       204088 if (defined $a) {
5227 1842 50       12468 croak "accuracy must be a number, not '$a'"
5228             unless $a =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
5229             }
5230              
5231 89935 100       184977 if (defined $p) {
5232 94 50       671 croak "precision must be a number, not '$p'"
5233             unless $p =~/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee][+-]?\d+)?\z/;
5234             }
5235              
5236             # now pick $a or $p, but only if we have got "arguments"
5237 89935 100       190356 if (!defined $a) {
5238 88093         195433 foreach ($self, @args) {
5239             # take the defined one, or if both defined, the one that is smaller
5240             $a = $_->{accuracy}
5241 129881 100 100     442394 if (defined $_->{accuracy}) && (!defined $a || $_->{accuracy} < $a);
      100        
5242             }
5243             }
5244 89935 100       180626 if (!defined $p) {
5245             # even if $a is defined, take $p, to signal error for both defined
5246 89841         147262 foreach ($self, @args) {
5247             # take the defined one, or if both defined, the one that is bigger
5248             # -2 > -3, and 3 > 2
5249             $p = $_->{precision}
5250 132797 100 66     308489 if (defined $_->{precision}) && (!defined $p || $_->{precision} > $p);
      66        
5251             }
5252             }
5253              
5254             # if still none defined, use globals
5255 89935 100 100     287136 unless (defined $a || defined $p) {
5256 63802         186113 $a = $class -> accuracy();
5257 63802         163974 $p = $class -> precision();
5258             }
5259              
5260             # A == 0 is useless, so undef it to signal no rounding
5261 89935 100 100     251248 $a = undef if defined $a && $a == 0;
5262              
5263             # no rounding today?
5264 89935 100 100     413201 return $self unless defined $a || defined $p;
5265              
5266             # set A and set P is an fatal error
5267 26169 100 100     82127 if (defined $a && defined $p) {
5268             #carp "can't specify both accuracy and precision";
5269 58         255 return $self -> bnan();
5270             }
5271              
5272             # Infs and NaNs are not rounded, but assign rounding parameters to them.
5273             #
5274             #if ($self -> is_inf() || $self -> is_nan()) {
5275             # $self->{accuracy} = $a;
5276             # $self->{precision} = $p;
5277             # return $self;
5278             #}
5279              
5280 26111 100       101430 $r = $class -> round_mode() unless defined $r;
5281 26111 50       126216 if ($r !~ /^(even|odd|[+-]inf|zero|trunc|common)$/) {
5282 0         0 croak("Unknown round mode '$r'");
5283             }
5284              
5285             # now round, by calling either bround or bfround:
5286 26111 100       50219 if (defined $a) {
5287             $self -> bround(int($a), $r)
5288 25911 100 100     187893 if !defined $self->{accuracy} || $self->{accuracy} >= $a;
5289             } else { # both can't be undefined due to early out
5290             $self -> bfround(int($p), $r)
5291 200 100 100     1462 if !defined $self->{precision} || $self->{precision} <= $p;
5292             }
5293              
5294             # bround() or bfround() already called bnorm() if nec.
5295 26111         89115 $self;
5296             }
5297              
5298             sub bround {
5299             # accuracy: +$n preserve $n digits from left,
5300             # -$n preserve $n digits from right (f.i. for 0.1234 style in MBF)
5301             # no-op for $n == 0
5302             # and overwrite the rest with 0's, return normalized number
5303             # do not return $x->bnorm(), but $x
5304              
5305 29306 50   29306 1 107903 my ($class, $x, @a) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5306              
5307             # Don't modify constant (read-only) objects.
5308              
5309 29306 50       91789 return $x if $x -> modify('bround');
5310              
5311 29306         80600 my ($scale, $mode) = $x->_scale_a(@a);
5312 29306 100       68395 return $x if !defined $scale; # no-op
5313              
5314 29304 100 100     79400 if ($x -> is_zero() || $scale == 0) {
5315             $x->{accuracy} = $scale
5316 101 100 66     567 if !defined $x->{accuracy} || $x->{accuracy} > $scale; # 3 > 2
5317 101         424 return $x;
5318             }
5319 29203 100       68515 return $x if !$x -> is_finite(); # inf, NaN
5320              
5321             # we have fewer digits than we want to scale to
5322 29191         84713 my $len = $x -> length();
5323             # convert $scale to a scalar in case it is an object (put's a limit on the
5324             # number length, but this would already limited by memory constraints),
5325             # makes it faster
5326 29191 50       64506 $scale = $scale -> numify() if ref ($scale);
5327              
5328             # scale < 0, but > -len (not >=!)
5329 29191 100 100     122878 if (($scale < 0 && $scale < -$len-1) || ($scale >= $len)) {
      100        
5330             $x->{accuracy} = $scale
5331 216 100 100     1262 if !defined $x->{accuracy} || $x->{accuracy} > $scale; # 3 > 2
5332 216         903 return $x;
5333             }
5334              
5335             # count of 0's to pad, from left (+) or right (-): 9 - +6 => 3, or |-6| => 6
5336 28975         48539 my ($pad, $digit_round, $digit_after);
5337 28975         47362 $pad = $len - $scale;
5338 28975 100       57373 $pad = abs($scale-1) if $scale < 0;
5339              
5340             # do not use digit(), it is very costly for binary => decimal
5341             # getting the entire string is also costly, but we need to do it only once
5342 28975         93506 my $xs = $LIB->_str($x->{value});
5343 28975         61697 my $pl = -$pad-1;
5344              
5345             # pad: 123: 0 => -1, at 1 => -2, at 2 => -3, at 3 => -4
5346             # pad+1: 123: 0 => 0, at 1 => -1, at 2 => -2, at 3 => -3
5347 28975         48015 $digit_round = '0';
5348 28975 100       75486 $digit_round = substr($xs, $pl, 1) if $pad <= $len;
5349 28975         50124 $pl++;
5350 28975 100       56463 $pl ++ if $pad >= $len;
5351 28975         46590 $digit_after = '0';
5352 28975 50       72553 $digit_after = substr($xs, $pl, 1) if $pad > 0;
5353              
5354             # in case of 01234 we round down, for 6789 up, and only in case 5 we look
5355             # closer at the remaining digits of the original $x, remember decision
5356 28975         43880 my $round_up = 1; # default round up
5357             $round_up -- if
5358             ($mode eq 'trunc') || # trunc by round down
5359             ($digit_after =~ /[01234]/) || # round down anyway,
5360             # 6789 => round up
5361             ($digit_after eq '5') && # not 5000...0000
5362             ($x->_scan_for_nonzero($pad, $xs, $len) == 0) &&
5363             (
5364             ($mode eq 'even') && ($digit_round =~ /[24680]/) ||
5365             ($mode eq 'odd') && ($digit_round =~ /[13579]/) ||
5366             ($mode eq '+inf') && ($x->{sign} eq '-') ||
5367 28975 100 100     219560 ($mode eq '-inf') && ($x->{sign} eq '+') ||
      100        
      100        
      100        
      100        
5368             ($mode eq 'zero') # round down if zero, sign adjusted below
5369             );
5370 28975         50408 my $put_back = 0; # not yet modified
5371              
5372 28975 100 66     99444 if (($pad > 0) && ($pad <= $len)) {
    50          
5373 28851         74780 substr($xs, -$pad, $pad) = '0' x $pad; # replace with '00...'
5374 28851         65223 $xs =~ s/^0+(\d)/$1/; # "00000" -> "0"
5375 28851         45011 $put_back = 1; # need to put back
5376             } elsif ($pad > $len) {
5377 124         656 $x -> bzero(); # round to '0'
5378             }
5379              
5380 28975 100       59858 if ($round_up) { # what gave test above?
5381 13945         21991 $put_back = 1; # need to put back
5382 13945 100       29116 $pad = $len, $xs = '0' x $pad if $scale < 0; # tlr: whack 0.51=>1.0
5383              
5384             # we modify directly the string variant instead of creating a number
5385             # and adding it, since that is faster (we already have the string)
5386 13945         22377 my $c = 0;
5387 13945         22158 $pad ++; # for $pad == $len case
5388 13945         30283 while ($pad <= $len) {
5389 15624         37059 $c = substr($xs, -$pad, 1) + 1;
5390 15624 100       37567 $c = '0' if $c eq '10';
5391 15624         28916 substr($xs, -$pad, 1) = $c;
5392 15624         23429 $pad++;
5393 15624 100       38906 last if $c != 0; # no overflow => early out
5394             }
5395 13945 100       32289 $xs = '1'.$xs if $c == 0;
5396             }
5397 28975 100       127119 $x->{value} = $LIB->_new($xs) if $put_back == 1; # put back, if needed
5398              
5399 28975 100       94922 $x->{accuracy} = $scale if $scale >= 0;
5400 28975 100       65398 if ($scale < 0) {
5401 137         419 $x->{accuracy} = $len+$scale;
5402 137 100       466 $x->{accuracy} = 0 if $scale < -$len;
5403             }
5404 28975         118280 $x;
5405             }
5406              
5407             sub bfround {
5408             # precision: round to the $Nth digit left (+$n) or right (-$n) from the '.'
5409             # $n == 0 || $n == 1 => round to integer
5410              
5411 219 50   219 1 1006 my ($class, $x, @p) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5412              
5413             # Don't modify constant (read-only) objects.
5414              
5415 219 50       786 return $x if $x -> modify('bfround');
5416              
5417 219         783 my ($scale, $mode) = $x->_scale_p(@p);
5418              
5419 219 50       626 return $x if !defined $scale;
5420              
5421             # no-op for Math::BigInt objects if $n <= 0
5422 219 100       740 $x = $x -> bround($x -> length() - $scale, $mode) if $scale > 0;
5423              
5424 219         534 $x->{accuracy} = undef;
5425 219         516 $x->{precision} = $scale; # store new precision
5426 219         552 $x;
5427             }
5428              
5429             sub fround {
5430             # Exists to make life easier for switch between MBF and MBI (should we
5431             # autoload fxxx() like MBF does for bxxx()?)
5432 0     0 0 0 my $x = shift;
5433 0 0       0 $x = __PACKAGE__ -> new($x) unless ref $x;
5434 0         0 $x -> bround(@_);
5435             }
5436              
5437             sub bfloor {
5438             # round towards minus infinity; no-op since it's already integer
5439 36 50   36 1 523 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5440              
5441             # Don't modify constant (read-only) objects.
5442              
5443 36 50       168 return $x if $x -> modify('bfloor');
5444              
5445 36         91 $x -> round(@r);
5446             }
5447              
5448             sub bceil {
5449             # round towards plus infinity; no-op since it's already int
5450 36 50   36 1 560 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5451              
5452             # Don't modify constant (read-only) objects.
5453              
5454 36 50       131 return $x if $x -> modify('bceil');
5455              
5456 36         88 $x -> round(@r);
5457             }
5458              
5459             sub bint {
5460             # round towards zero; no-op since it's already integer
5461 38 50   38 1 532 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5462              
5463             # Don't modify constant (read-only) objects.
5464              
5465 38 50       145 return $x if $x -> modify('bint');
5466              
5467 38         155 $x->round(@r);
5468             }
5469              
5470             ###############################################################################
5471             # Other mathematical methods
5472             ###############################################################################
5473              
5474             sub bgcd {
5475             # GCD -- Euclid's algorithm, variant C (Knuth Vol 3, pg 341 ff)
5476              
5477             # Class::method(...) -> Class->method(...)
5478 97 100 66 97 1 4416 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
5479             ($_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i &&
5480             $_[0] !~ /^(inf|nan)/i)))
5481             {
5482             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
5483             # " use is as a method instead";
5484 1         6 unshift @_, __PACKAGE__;
5485             }
5486              
5487 97         347 my ($class, @args) = objectify(0, @_);
5488              
5489             # Pre-process list of operands.
5490              
5491 97         206 for my $arg (@args) {
5492 181 100       393 return $class -> bnan() unless $arg -> is_int();
5493             }
5494              
5495             # Upgrade?
5496              
5497 64         190 my $upg = $class -> upgrade();
5498 64 100       142 if ($upg) {
5499 12         30 my $do_upgrade = 0;
5500 12         19 for my $arg (@args) {
5501 26 50       60 unless ($arg -> isa(__PACKAGE__)) {
5502 0         0 $do_upgrade = 1;
5503 0         0 last;
5504             }
5505             }
5506 12 50       24 if ($do_upgrade) {
5507 0         0 my $x = shift @args;
5508 0         0 $x -> _upg();
5509 0         0 return $x -> bgcd(@args);
5510             }
5511             }
5512              
5513 64         106 my $x = shift @args;
5514 64         183 $x = $x -> copy(); # bgcd() and blcm() never modify any operands
5515 64         156 while (@args) {
5516 74         97 my $y = shift @args;
5517 74         305 $x->{value} = $LIB->_gcd($x->{value}, $y->{value});
5518 74 100       261 last if $LIB->_is_one($x->{value});
5519             }
5520              
5521 64         227 return $x -> babs();
5522             }
5523              
5524             sub blcm {
5525             # Least Common Multiple
5526              
5527             # Class::method(...) -> Class->method(...)
5528 35 100 66 35 1 2309 unless (@_ && (defined(blessed($_[0])) && $_[0] -> isa(__PACKAGE__) ||
      66        
5529             ($_[0] =~ /^[a-z]\w*(?:::[a-z]\w*)*$/i &&
5530             $_[0] !~ /^(inf|nan)/i)))
5531             {
5532             #carp "Using ", (caller(0))[3], "() as a function is deprecated;",
5533             # " use is as a method instead";
5534 1         4 unshift @_, __PACKAGE__;
5535             }
5536              
5537 35         103 my ($class, @args) = objectify(0, @_);
5538              
5539             # Pre-process list of operands.
5540              
5541 35         67 for my $arg (@args) {
5542 65 100       123 return $class -> bnan() unless $arg -> is_finite();
5543             }
5544              
5545 23         36 for my $arg (@args) {
5546 41 100       108 return $class -> bzero() if $arg -> is_zero();
5547             }
5548              
5549             # Upgrade?
5550              
5551 11         35 my $upg = $class -> upgrade();
5552 11 100       32 if ($upg) {
5553 2         4 my $do_upgrade = 0;
5554 2         4 for my $arg (@args) {
5555 4 50       10 unless ($arg -> isa(__PACKAGE__)) {
5556 0         0 $do_upgrade = 1;
5557 0         0 last;
5558             }
5559             }
5560 2 50       6 if ($do_upgrade) {
5561 0         0 my $x = shift @args;
5562 0         0 $x -> _upg();
5563 0         0 return $x -> bgcd(@args);
5564             }
5565             }
5566              
5567 11         20 my $x = shift @args;
5568 11         37 $x = $x -> copy(); # bgcd() and blcm() never modify any operands
5569              
5570 11         34 while (@args) {
5571 14         26 my $y = shift @args;
5572 14 50       42 return $x -> bnan() if !$y -> is_int(); # is $y not integer?
5573 14         92 $x -> {value} = $LIB->_lcm($x -> {value}, $y -> {value});
5574             }
5575              
5576 11         39 return $x -> babs();
5577             }
5578              
5579             ###############################################################################
5580             # Object property methods
5581             ###############################################################################
5582              
5583             sub sign {
5584             # return the sign of the number: +/-/-inf/+inf/NaN
5585 923 50   923 1 2857 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5586              
5587 923 50       2054 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5588              
5589 923         4379 $x->{sign};
5590             }
5591              
5592             sub digit {
5593             # return the nth decimal digit, negative values count backward, 0 is right
5594 87 100   87 1 938 my (undef, $x, $n, @r) = ref($_[0]) ? (undef, @_) : objectify(1, @_);
5595              
5596 87 50       231 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5597              
5598 87 100       349 $n = $n -> numify() if ref($n);
5599 87   100     482 $LIB->_digit($x->{value}, $n || 0);
5600             }
5601              
5602             sub bdigitsum {
5603             # like digitsum(), but assigns the result to the invocand
5604 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5605              
5606             # Don't modify constant (read-only) objects.
5607              
5608 0 0       0 return $x if $x -> modify('bdigitsum');
5609              
5610 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5611              
5612 0 0       0 return $x if $x -> is_nan();
5613 0 0       0 return $x -> bnan() if $x -> is_inf();
5614              
5615 0         0 $x -> {value} = $LIB -> _digitsum($x -> {value});
5616 0         0 $x -> {sign} = '+';
5617 0         0 return $x;
5618             }
5619              
5620             sub digitsum {
5621             # compute sum of decimal digits and return it
5622 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5623              
5624 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5625              
5626 0 0       0 return $class -> bnan() if $x -> is_nan();
5627 0 0       0 return $class -> bnan() if $x -> is_inf();
5628              
5629 0         0 my $y = $class -> bzero();
5630 0         0 $y -> {value} = $LIB -> _digitsum($x -> {value});
5631 0         0 $y -> round(@r);
5632             }
5633              
5634             sub length {
5635 29343 50   29343 1 92535 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5636              
5637 29343 50       61469 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5638              
5639 29343         79947 my $e = $LIB->_len($x->{value});
5640 29343 100       79365 wantarray ? ($e, 0) : $e;
5641             }
5642              
5643             sub mantissa {
5644             # return the mantissa (compatible to Math::BigFloat, e.g. reduced)
5645 68 50   68 1 595 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5646              
5647 68 50       198 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5648              
5649 68 100       233 if (!$x -> is_finite()) {
5650             # for NaN, +inf, -inf: keep the sign
5651 24         123 return $class -> new($x->{sign}, @r);
5652             }
5653 44         180 my $m = $x -> copy();
5654 44         168 $m -> precision(undef);
5655 44         133 $m -> accuracy(undef);
5656              
5657             # that's a bit inefficient:
5658 44         232 my $zeros = $LIB->_zeros($m->{value});
5659 44 100       171 $m = $m -> brsft($zeros, 10) if $zeros != 0;
5660 44         127 $m -> round(@r);
5661             }
5662              
5663             sub exponent {
5664             # return a copy of the exponent (here always 0, NaN or 1 for $m == 0)
5665 72 50   72 1 524 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5666              
5667 72 50       185 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5668              
5669 72 100       182 if (!$x -> is_finite()) {
5670 24         54 my $s = $x->{sign};
5671 24         92 $s =~ s/^[+-]//; # NaN, -inf, +inf => NaN or inf
5672 24         77 return $class -> new($s, @r);
5673             }
5674 48 100       150 return $class -> bzero(@r) if $x -> is_zero();
5675              
5676             # 12300 => 2 trailing zeros => exponent is 2
5677 40         211 $class -> new($LIB->_zeros($x->{value}), @r);
5678             }
5679              
5680             sub parts {
5681             # return a copy of both the exponent and the mantissa
5682 36 50   36 1 509 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5683              
5684 36 50       97 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5685              
5686 36         141 ($x -> mantissa(@r), $x -> exponent(@r));
5687             }
5688              
5689             # Parts used for scientific notation with significand/mantissa and exponent as
5690             # integers. E.g., "12345.6789" is returned as "123456789" (mantissa) and "-4"
5691             # (exponent).
5692              
5693             sub sparts {
5694 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5695              
5696 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5697              
5698             # Not-a-number.
5699              
5700 0 0       0 if ($x -> is_nan()) {
5701 0         0 my $mant = $class -> bnan(@r); # mantissa
5702 0 0       0 return $mant unless wantarray; # scalar context
5703 0         0 my $expo = $class -> bnan(@r); # exponent
5704 0         0 return $mant, $expo; # list context
5705             }
5706              
5707             # Infinity.
5708              
5709 0 0       0 if ($x -> is_inf()) {
5710 0         0 my $mant = $class -> binf($x->{sign}, @r); # mantissa
5711 0 0       0 return $mant unless wantarray; # scalar context
5712 0         0 my $expo = $class -> binf('+', @r); # exponent
5713 0         0 return $mant, $expo; # list context
5714             }
5715              
5716             # Finite number.
5717              
5718 0         0 my $mant = $x -> copy();
5719 0         0 my $nzeros = $LIB -> _zeros($mant -> {value});
5720              
5721             $mant -> {value}
5722 0 0       0 = $LIB -> _rsft($mant -> {value}, $LIB -> _new($nzeros), 10)
5723             if $nzeros != 0;
5724 0 0       0 return $mant unless wantarray;
5725              
5726 0         0 my $expo = $class -> new($nzeros, @r);
5727 0         0 return $mant, $expo;
5728             }
5729              
5730             # Parts used for normalized notation with significand/mantissa as either 0 or a
5731             # number in the semi-open interval [1,10). E.g., "12345.6789" is returned as
5732             # "1.23456789" and "4".
5733              
5734             sub nparts {
5735 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5736              
5737 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5738              
5739             # Not-a-Number and Infinity.
5740              
5741 0 0 0     0 return $x -> sparts(@r) if $x -> is_nan() || $x -> is_inf();
5742              
5743             # Finite number.
5744              
5745 0         0 my ($mant, $expo) = $x -> sparts(@r);
5746 0 0       0 if ($mant -> bcmp(0)) {
5747 0         0 my ($ndigtot, $ndigfrac) = $mant -> length();
5748 0         0 my $expo10adj = $ndigtot - $ndigfrac - 1;
5749              
5750 0 0       0 if ($expo10adj > 0) { # if mantissa is not an integer
5751 0 0       0 return $x -> _upg() -> nparts(@r) if $class -> upgrade();
5752 0         0 $mant -> bnan(@r);
5753 0 0       0 return $mant unless wantarray;
5754 0         0 $expo -> badd($expo10adj, @r);
5755 0         0 return $mant, $expo;
5756             }
5757             }
5758              
5759 0 0       0 return $mant unless wantarray;
5760 0         0 return $mant, $expo;
5761             }
5762              
5763             # Parts used for engineering notation with significand/mantissa as either 0 or
5764             # a number in the semi-open interval [1,1000) and the exponent is a multiple of
5765             # 3. E.g., "12345.6789" is returned as "12.3456789" and "3".
5766              
5767             sub eparts {
5768 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5769              
5770 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5771              
5772             # Not-a-number and Infinity.
5773              
5774 0 0 0     0 return $x -> sparts(@r) if $x -> is_nan() || $x -> is_inf();
5775              
5776             # Finite number.
5777              
5778 0         0 my ($mant, $expo) = $x -> sparts(@r);
5779              
5780 0 0       0 if ($mant -> bcmp(0)) {
5781 0         0 my $ndigmant = $mant -> length();
5782 0         0 $expo -> badd($ndigmant, @r);
5783              
5784             # $c is the number of digits that will be in the integer part of the
5785             # final mantissa.
5786              
5787 0         0 my $c = $expo -> copy() -> bdec() -> bmod(3) -> binc();
5788 0         0 $expo -> bsub($c);
5789              
5790 0 0       0 if ($ndigmant > $c) {
5791 0 0       0 return $x -> _upg() -> eparts(@r) if $class -> upgrade();
5792 0         0 $mant -> bnan(@r);
5793 0 0       0 return $mant unless wantarray;
5794 0         0 return $mant, $expo;
5795             }
5796              
5797 0         0 $mant -> blsft($c - $ndigmant, 10, @r);
5798             }
5799              
5800 0 0       0 return $mant unless wantarray;
5801 0         0 return $mant, $expo;
5802             }
5803              
5804             # Parts used for decimal notation, e.g., "12345.6789" is returned as "12345"
5805             # (integer part) and "0.6789" (fraction part).
5806              
5807             sub dparts {
5808 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5809              
5810 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5811              
5812             # Not-a-number.
5813              
5814 0 0       0 if ($x -> is_nan()) {
5815 0         0 my $int = $class -> bnan(@r);
5816 0 0       0 return $int unless wantarray;
5817 0         0 my $frc = $class -> bzero(@r); # or NaN?
5818 0         0 return $int, $frc;
5819             }
5820              
5821             # Infinity.
5822              
5823 0 0       0 if ($x -> is_inf()) {
5824 0         0 my $int = $class -> binf($x->{sign}, @r);
5825 0 0       0 return $int unless wantarray;
5826 0         0 my $frc = $class -> bzero(@r);
5827 0         0 return $int, $frc;
5828             }
5829              
5830             # Finite number.
5831              
5832 0         0 my $int = $x -> copy() -> round(@r);
5833 0 0       0 return $int unless wantarray;
5834              
5835 0         0 my $frc = $class -> bzero(@r);
5836 0         0 return $int, $frc;
5837             }
5838              
5839             # Fractional parts with the numerator and denominator as integers. E.g.,
5840             # "123.4375" is returned as "1975" and "16".
5841              
5842             sub fparts {
5843 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5844              
5845 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5846              
5847             # NaN => NaN/NaN
5848              
5849 0 0       0 if ($x -> is_nan()) {
5850 0 0       0 return $class -> bnan(@r) unless wantarray;
5851 0         0 return $class -> bnan(@r), $class -> bnan(@r);
5852             }
5853              
5854             # ±Inf => ±Inf/1
5855              
5856 0 0       0 if ($x -> is_inf()) {
5857 0         0 my $numer = $class -> binf($x->{sign}, @r);
5858 0 0       0 return $numer unless wantarray;
5859 0         0 my $denom = $class -> bone(@r);
5860 0         0 return $numer, $denom;
5861             }
5862              
5863             # N => N/1
5864              
5865 0         0 my $numer = $x -> copy() -> round(@r);
5866 0 0       0 return $numer unless wantarray;
5867              
5868 0         0 my $denom = $x -> copy();
5869 0         0 $denom -> {sign} = "+";
5870 0         0 $denom -> {value} = $LIB -> _one();
5871 0         0 $denom -> round(@r);
5872 0         0 return $numer, $denom;
5873             }
5874              
5875             sub numerator {
5876 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5877              
5878 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5879              
5880 0         0 return $x -> copy() -> round(@r);
5881             }
5882              
5883             sub denominator {
5884 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5885              
5886 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5887              
5888 0 0       0 return $x -> is_nan() ? $class -> bnan(@r) : $class -> bone(@r);
5889             }
5890              
5891             ###############################################################################
5892             # String conversion methods
5893             ###############################################################################
5894              
5895             sub bstr {
5896 12376 100   12376 1 2753314 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5897              
5898 12376 50       35117 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5899              
5900             # Inf and NaN
5901              
5902 12376 100 100     57012 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
5903 2823 100       10573 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
5904 581         4288 return 'inf'; # +inf
5905             }
5906              
5907             # Upgrade?
5908              
5909 9553 50 66     34216 $x -> _upg() -> bstr(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
5910              
5911             # Finite number
5912              
5913 9553         57264 my $str = $LIB->_str($x->{value});
5914 9553 100       73372 return $x->{sign} eq '-' ? "-$str" : $str;
5915             }
5916              
5917             # Scientific notation with significand/mantissa as an integer, e.g., "12345" is
5918             # written as "1.2345e+4".
5919              
5920             sub bsstr {
5921 66 100   66 1 16237 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5922              
5923 66 50       227 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5924              
5925             # Inf and NaN
5926              
5927 66 100 100     299 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
5928 18 100       84 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
5929 7         77 return 'inf'; # +inf
5930             }
5931              
5932             # Upgrade?
5933              
5934 48 50 66     160 $x -> _upg() -> bsstr(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
5935              
5936             # Finite number
5937              
5938 48         333 my $expo = $LIB -> _zeros($x->{value});
5939 48         246 my $mant = $LIB -> _str($x->{value});
5940 48 100       161 $mant = substr($mant, 0, -$expo) if $expo; # strip trailing zeros
5941              
5942 48 100       685 ($x->{sign} eq '-' ? '-' : '') . $mant . 'e+' . $expo;
5943             }
5944              
5945             # Normalized notation, e.g., "12345" is written as "1.2345e+4".
5946              
5947             sub bnstr {
5948 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5949              
5950 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5951              
5952             # Inf and NaN
5953              
5954 0 0 0     0 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
5955 0 0       0 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
5956 0         0 return 'inf'; # +inf
5957             }
5958              
5959             # Upgrade?
5960              
5961 0 0 0     0 $x -> _upg() -> bnstr(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
5962              
5963             # Finite number
5964              
5965 0         0 my $expo = $LIB -> _zeros($x->{value});
5966 0         0 my $mant = $LIB -> _str($x->{value});
5967 0 0       0 $mant = substr($mant, 0, -$expo) if $expo; # strip trailing zeros
5968              
5969 0         0 my $mantlen = CORE::length($mant);
5970 0 0       0 if ($mantlen > 1) {
5971 0         0 $expo += $mantlen - 1; # adjust exponent
5972 0         0 substr $mant, 1, 0, "."; # insert decimal point
5973             }
5974              
5975 0 0       0 ($x->{sign} eq '-' ? '-' : '') . $mant . 'e+' . $expo;
5976             }
5977              
5978             # Engineering notation, e.g., "12345" is written as "12.345e+3".
5979              
5980             sub bestr {
5981 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
5982              
5983 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
5984              
5985             # Inf and NaN
5986              
5987 0 0 0     0 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
5988 0 0       0 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
5989 0         0 return 'inf'; # +inf
5990             }
5991              
5992             # Upgrade?
5993              
5994 0 0 0     0 $x -> _upg() -> bestr(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
5995              
5996             # Finite number
5997              
5998 0         0 my $expo = $LIB -> _zeros($x->{value}); # number of trailing zeros
5999 0         0 my $mant = $LIB -> _str($x->{value}); # mantissa as a string
6000 0 0       0 $mant = substr($mant, 0, -$expo) if $expo; # strip trailing zeros
6001 0         0 my $mantlen = CORE::length($mant); # length of mantissa
6002 0         0 $expo += $mantlen;
6003              
6004 0         0 my $dotpos = ($expo - 1) % 3 + 1; # offset of decimal point
6005 0         0 $expo -= $dotpos;
6006              
6007 0 0       0 if ($dotpos < $mantlen) {
    0          
6008 0         0 substr $mant, $dotpos, 0, "."; # insert decimal point
6009             } elsif ($dotpos > $mantlen) {
6010 0         0 $mant .= "0" x ($dotpos - $mantlen); # append zeros
6011             }
6012              
6013 0 0       0 ($x->{sign} eq '-' ? '-' : '') . $mant . 'e+' . $expo;
6014             }
6015              
6016             # Decimal notation, e.g., "12345" (no exponent).
6017              
6018             sub bdstr {
6019 469 50   469 1 1576 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6020              
6021 469 50       1249 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6022              
6023             # Inf and NaN
6024              
6025 469 50 66     1769 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
6026 0 0       0 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
6027 0         0 return 'inf'; # +inf
6028             }
6029              
6030             # Upgrade?
6031              
6032 469 50 66     1256 $x -> _upg() -> bdstr(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6033              
6034             # Finite number
6035              
6036 469 100       3120 ($x->{sign} eq '-' ? '-' : '') . $LIB->_str($x->{value});
6037             }
6038              
6039             # Fraction notation, e.g., "123.4375" is written as "1975/16", but "123" is
6040             # written as "123", not "123/1".
6041              
6042             sub bfstr {
6043 1021 50   1021 1 2603 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6044              
6045 1021 50       2011 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6046              
6047             # Inf and NaN
6048              
6049 1021 100 100     2747 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
6050 68 50       213 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
6051 0         0 return 'inf'; # +inf
6052             }
6053              
6054             # Upgrade?
6055              
6056 953 50 66     1954 $x -> _upg() -> bfstr(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6057              
6058             # Finite number
6059              
6060 953 100       4332 ($x->{sign} eq '-' ? '-' : '') . $LIB->_str($x->{value});
6061             }
6062              
6063             sub to_hex {
6064             # return as hex string with no prefix
6065              
6066 36 50   36 1 666 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6067              
6068 36 50       90 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6069              
6070             # Inf and NaN
6071              
6072 36 100 100     195 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
6073 12 100       48 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
6074 4         50 return 'inf'; # +inf
6075             }
6076              
6077             # Upgrade?
6078              
6079 24 50 66     82 return $x -> _upg() -> to_hex(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6080              
6081             # Finite number
6082              
6083 24         161 my $hex = $LIB->_to_hex($x->{value});
6084 24 100       300 return $x->{sign} eq '-' ? "-$hex" : $hex;
6085             }
6086              
6087             sub to_oct {
6088             # return as octal string with no prefix
6089              
6090 40 50   40 1 667 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6091              
6092 40 50       122 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6093              
6094             # Inf and NaN
6095              
6096 40 100 100     160 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
6097 12 100       48 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
6098 4         4124 return 'inf'; # +inf
6099             }
6100              
6101             # Upgrade?
6102              
6103 28 50 66     84 return $x -> _upg() -> to_oct(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6104              
6105             # Finite number
6106              
6107 28         174 my $oct = $LIB->_to_oct($x->{value});
6108 28 100       343 return $x->{sign} eq '-' ? "-$oct" : $oct;
6109             }
6110              
6111             sub to_bin {
6112             # return as binary string with no prefix
6113              
6114 93 50   93 1 914 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6115              
6116 93 50       226 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6117              
6118             # Inf and NaN
6119              
6120 93 100 100     446 if ($x->{sign} ne '+' && $x->{sign} ne '-') {
6121 12 100       51 return $x->{sign} unless $x -> is_inf("+"); # -inf, NaN
6122 4         51 return 'inf'; # +inf
6123             }
6124              
6125             # Upgrade?
6126              
6127 81 50 66     301 return $x -> _upg() -> to_bin(@r) if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6128              
6129             # Finite number
6130              
6131 81         488 my $bin = $LIB->_to_bin($x->{value});
6132 81 100       625 return $x->{sign} eq '-' ? "-$bin" : $bin;
6133             }
6134              
6135             sub to_bytes {
6136             # return a byte string
6137              
6138 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6139              
6140 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6141              
6142 0 0 0     0 croak("to_bytes() requires a finite, non-negative integer")
6143             if $x -> is_neg() || ! $x -> is_int();
6144              
6145 0 0 0     0 return $x -> _upg() -> to_bytes(@r)
6146             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6147              
6148 0 0       0 croak("to_bytes() requires a newer version of the $LIB library.")
6149             unless $LIB -> can('_to_bytes');
6150              
6151 0         0 return $LIB->_to_bytes($x->{value});
6152             }
6153              
6154             sub to_ieee754 {
6155 0 0   0 1 0 my ($class, $x, $format, @r) = ref($_[0]) ? (ref($_[0]), @_)
6156             : objectify(1, @_);
6157              
6158 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6159              
6160 0 0 0     0 return $x -> _upg() -> to_ieee754($format, @r)
6161             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6162              
6163 0 0 0     0 croak("the value to convert must be an integer, +/-infinity, or NaN")
      0        
6164             unless $x -> is_int() || $x -> is_inf() || $x -> is_nan();
6165              
6166 0         0 return $x -> as_float() -> to_ieee754($format);
6167             }
6168              
6169             sub to_fp80 {
6170 0 0   0 1 0 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_)
6171             : objectify(1, @_);
6172              
6173 0 0 0     0 return $x -> _upg() -> to_fp80(@r)
6174             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6175              
6176 0 0 0     0 croak("the value to convert must be an integer, +/-infinity, or NaN")
      0        
6177             unless $x -> is_int() || $x -> is_inf() || $x -> is_nan();
6178              
6179 0         0 return $x -> as_float(@r) -> to_fp80();
6180             }
6181              
6182             sub to_base {
6183             # return a base anything string
6184              
6185             # $cs is the collation sequence
6186 0 0 0 0 1 0 my ($class, $x, $base, $cs, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
6187             ? (ref($_[0]), @_) : objectify(2, @_);
6188              
6189 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6190              
6191 0 0 0     0 croak("the value to convert must be a finite, non-negative integer")
6192             if $x -> is_neg() || !$x -> is_int();
6193              
6194 0 0 0     0 croak("the base must be a finite integer >= 2")
6195             if $base < 2 || ! $base -> is_int();
6196              
6197             # If no collating sequence is given, pass some of the conversions to
6198             # methods optimized for those cases.
6199              
6200 0 0       0 unless (defined $cs) {
6201 0 0       0 return $x -> to_bin() if $base == 2;
6202 0 0       0 return $x -> to_oct() if $base == 8;
6203 0 0       0 return uc $x -> to_hex() if $base == 16;
6204 0 0       0 return $x -> bstr() if $base == 10;
6205             }
6206              
6207 0 0       0 croak("to_base() requires a newer version of the $LIB library.")
6208             unless $LIB -> can('_to_base');
6209              
6210 0 0 0     0 return $x -> _upg() -> to_basen($base, $cs, @r)
      0        
6211             if $class -> upgrade() && (!$x -> isa(__PACKAGE__) ||
6212             !$base -> isa(__PACKAGE__));
6213              
6214             return $LIB->_to_base($x->{value}, $base -> {value},
6215 0 0       0 defined($cs) ? $cs : ());
6216             }
6217              
6218             sub to_base_num {
6219             # return a base anything array ref, e.g.,
6220             # Math::BigInt -> new(255) -> to_base_num(10) returns [2, 5, 5];
6221              
6222             # $cs is the collation sequence
6223 0 0 0 0 1 0 my ($class, $x, $base, @r) = ref($_[0]) && ref($_[0]) eq ref($_[1])
6224             ? (ref($_[0]), @_) : objectify(2, @_);
6225              
6226 0 0       0 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6227              
6228 0 0 0     0 croak("the value to convert must be a finite non-negative integer")
6229             if $x -> is_neg() || !$x -> is_int();
6230              
6231 0 0 0     0 croak("the base must be a finite integer >= 2")
6232             if $base < 2 || ! $base -> is_int();
6233              
6234 0 0       0 croak("to_base() requires a newer version of the $LIB library.")
6235             unless $LIB -> can('_to_base');
6236              
6237 0 0 0     0 return $x -> _upg() -> to_base_num($base, @r)
      0        
6238             if $class -> upgrade() && (!$x -> isa(__PACKAGE__) ||
6239             !$base -> isa(__PACKAGE__));
6240              
6241             # Get a reference to an array of library thingies, and replace each element
6242             # with a Math::BigInt object using that thingy.
6243              
6244 0         0 my $vals = $LIB -> _to_base_num($x->{value}, $base -> {value});
6245              
6246 0         0 for my $i (0 .. $#$vals) {
6247 0         0 my $x = $class -> bzero();
6248 0         0 $x -> {value} = $vals -> [$i];
6249 0         0 $vals -> [$i] = $x;
6250             }
6251              
6252 0         0 return $vals;
6253             }
6254              
6255             sub as_hex {
6256             # return as hex string, with prefixed 0x
6257              
6258 36 50   36 1 667 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6259              
6260 36 50       91 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6261              
6262 36 100       108 return $x -> bstr() if !$x -> is_finite(); # inf, nan etc
6263              
6264 24 50 66     77 return $x -> _upg() -> as_hex(@r)
6265             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6266              
6267 24         135 my $hex = $LIB->_as_hex($x->{value});
6268 24 100       316 return $x->{sign} eq '-' ? "-$hex" : $hex;
6269             }
6270              
6271             sub as_oct {
6272             # return as octal string, with prefixed 0
6273              
6274 40 50   40 1 682 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6275              
6276 40 50       112 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6277              
6278 40 100       108 return $x -> bstr() if !$x -> is_finite(); # inf, nan etc
6279              
6280 28 50 66     84 return $x -> _upg() -> as_oct(@r)
6281             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6282              
6283 28         143 my $oct = $LIB->_as_oct($x->{value});
6284 28 100       464 return $x->{sign} eq '-' ? "-$oct" : $oct;
6285             }
6286              
6287             sub as_bin {
6288             # return as binary string, with prefixed 0b
6289              
6290 39 50   39 1 668 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6291              
6292 39 50       94 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6293              
6294 39 100       104 return $x -> bstr() if !$x -> is_finite(); # inf, nan etc
6295              
6296 27 50 66     94 return $x -> _upg() -> as_bin(@r)
6297             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6298              
6299 27         126 my $bin = $LIB->_as_bin($x->{value});
6300 27 100       347 return $x->{sign} eq '-' ? "-$bin" : $bin;
6301             }
6302              
6303             *as_bytes = \&to_bytes;
6304              
6305             ###############################################################################
6306             # Other conversion methods
6307             ###############################################################################
6308              
6309             sub numify {
6310             # Make a Perl scalar number from a Math::BigInt object.
6311 545 50   545 1 2180 my ($class, $x, @r) = ref($_[0]) ? (ref($_[0]), @_) : objectify(1, @_);
6312              
6313 545 50       1252 carp "Rounding is not supported for ", (caller(0))[3], "()" if @r;
6314              
6315 545 50       1689 if ($x -> is_nan()) {
6316 0         0 require Math::Complex;
6317 0         0 my $inf = $Math::Complex::Inf;
6318 0         0 return $inf - $inf;
6319             }
6320              
6321 545 50       1495 if ($x -> is_inf()) {
6322 0         0 require Math::Complex;
6323 0         0 my $inf = $Math::Complex::Inf;
6324 0 0       0 return $x -> is_negative() ? -$inf : $inf;
6325             }
6326              
6327 545 50 66     1666 return $x -> _upg() -> numify(@r)
6328             if $class -> upgrade() && !$x -> isa(__PACKAGE__);
6329              
6330 545         2643 my $num = 0 + $LIB->_num($x->{value});
6331 545 100       2448 return $x->{sign} eq '-' ? -$num : $num;
6332             }
6333              
6334             ###############################################################################
6335             # Private methods and functions.
6336             ###############################################################################
6337              
6338             sub _trailing_zeros {
6339             # return the amount of trailing zeros in $x (as scalar)
6340 0     0   0 my $x = shift;
6341 0 0       0 $x = __PACKAGE__ -> new($x) unless ref $x;
6342              
6343 0 0       0 return 0 if !$x -> is_finite(); # NaN, inf, -inf etc
6344              
6345 0         0 $LIB->_zeros($x->{value}); # must handle odd values, 0 etc
6346             }
6347              
6348             sub _scan_for_nonzero {
6349             # internal, used by bround() to scan for non-zeros after a '5'
6350 3338     3338   9916 my ($x, $pad, $xs, $len) = @_;
6351              
6352 3338 100       8599 return 0 if $len == 1; # "5" is trailed by invisible zeros
6353 3315         6337 my $follow = $pad - 1;
6354 3315 100 66     36486 return 0 if $follow > $len || $follow < 1;
6355              
6356             # use the string form to check whether only '0's follow or not
6357 2606 100       20373 substr ($xs, -$follow) =~ /[^0]/ ? 1 : 0;
6358             }
6359              
6360             sub _find_round_parameters {
6361             # After any operation or when calling round(), the result is rounded by
6362             # regarding the A & P from arguments, local parameters, or globals.
6363              
6364             # !!!!!!! If you change this, remember to change round(), too! !!!!!!!!!!
6365              
6366             # This procedure finds the round parameters, but it is for speed reasons
6367             # duplicated in round. Otherwise, it is tested by the testsuite and used
6368             # by bdiv().
6369              
6370             # returns ($self) or ($self, $a, $p, $r) - sets $self to NaN of both A and
6371             # P were requested/defined (locally or globally or both)
6372              
6373 10901     10901   86360 my ($self, $a, $p, $r, @args) = @_;
6374             # $a accuracy, if given by caller
6375             # $p precision, if given by caller
6376             # $r round_mode, if given by caller
6377             # @args all 'other' arguments (0 for unary, 1 for binary ops)
6378              
6379 10901         23154 my $class = ref($self); # find out class of argument(s)
6380              
6381             # convert to normal scalar for speed and correctness in inner parts
6382 10901 50 100     46670 $a = $a -> can('numify') ? $a -> numify() : "$a" if defined $a && ref($a);
    100          
6383 10901 0 66     29751 $p = $p -> can('numify') ? $p -> numify() : "$p" if defined $p && ref($p);
    50          
6384              
6385             # now pick $a or $p, but only if we have got "arguments"
6386 10901 100       26062 if (!defined $a) {
6387 1098         2763 foreach ($self, @args) {
6388             # take the defined one, or if both defined, the one that is smaller
6389             $a = $_->{accuracy}
6390 1760 50 33     5418 if (defined $_->{accuracy}) && (!defined $a || $_->{accuracy} < $a);
      66        
6391             }
6392             }
6393 10901 100       26236 if (!defined $p) {
6394             # even if $a is defined, take $p, to signal error for both defined
6395 10849         25073 foreach ($self, @args) {
6396             # take the defined one, or if both defined, the one that is bigger
6397             # -2 > -3, and 3 > 2
6398             $p = $_->{precision}
6399 20306 50 33     53228 if (defined $_->{precision}) && (!defined $p || $_->{precision} > $p);
      66        
6400             }
6401             }
6402              
6403             # if still none defined, use globals (#2)
6404 10901 100       26291 $a = $class -> accuracy() unless defined $a;
6405 10901 100       39842 $p = $class -> precision() unless defined $p;
6406              
6407             # A == 0 is useless, so undef it to signal no rounding
6408 10901 100 100     44794 $a = undef if defined $a && $a == 0;
6409              
6410             # no rounding today?
6411 10901 100 100     32382 return ($self) unless defined $a || defined $p; # early out
6412              
6413             # set A and set P is an fatal error
6414 9886 100 100     36003 return ($self -> bnan()) if defined $a && defined $p; # error
6415              
6416 9877 100       44398 $r = $class -> round_mode() unless defined $r;
6417 9877 100       55683 if ($r !~ /^(even|odd|[+-]inf|zero|trunc|common)$/) {
6418 3         785 croak("Unknown round mode '$r'");
6419             }
6420              
6421 9874 100       26540 $a = int($a) if defined $a;
6422 9874 100       22462 $p = int($p) if defined $p;
6423              
6424 9874         50990 ($self, $a, $p, $r);
6425             }
6426              
6427             # Return true if the input is numeric and false if it is a string.
6428              
6429             sub _is_numeric {
6430 0     0   0 shift; # class name
6431 0         0 my $value = shift;
6432 50     50   692 no warnings 'numeric';
  50         119  
  50         253022  
6433             # detect numbers
6434             # string & "" -> ""
6435             # number & "" -> 0 (with warning)
6436             # nan and inf can detect as numbers, so check with * 0
6437 0 0       0 return unless CORE::length((my $dummy = "") & $value);
6438 0 0       0 return unless 0 + $value eq $value;
6439 0 0       0 return 1 if $value * 0 == 0;
6440 0         0 return -1; # Inf/NaN
6441             }
6442              
6443             # Trims the sign of the significand, the (absolute value of the) significand,
6444             # the sign of the exponent, and the (absolute value of the) exponent. The
6445             # returned values have no underscores ("_") or unnecessary leading or trailing
6446             # zeros.
6447              
6448             sub _trim_split_parts {
6449 8671     8671   15905 shift; # class name
6450              
6451 8671   100     43904 my $sig_sgn = shift() || '+';
6452 8671   100     31884 my $sig_str = shift() || '0';
6453 8671   100     36940 my $exp_sgn = shift() || '+';
6454 8671   100     52448 my $exp_str = shift() || '0';
6455              
6456 8671         22056 $sig_str =~ tr/_//d; # "1.0_0_0" -> "1.000"
6457 8671         32188 $sig_str =~ s/^0+//; # "01.000" -> "1.000"
6458 8671 100       36380 $sig_str =~ s/\.0*$// # "1.000" -> "1"
6459             || $sig_str =~ s/(\..*[^0])0+$/$1/; # "1.010" -> "1.01"
6460 8671 100       24519 $sig_str = '0' unless CORE::length($sig_str);
6461              
6462 8671 100       36883 return '+', '0', '+', '0' if $sig_str eq '0';
6463              
6464 6086         11563 $exp_str =~ tr/_//d; # "01_234" -> "01234"
6465 6086         24456 $exp_str =~ s/^0+//; # "01234" -> "1234"
6466 6086 100       18606 $exp_str = '0' unless CORE::length($exp_str);
6467 6086 100       17526 $exp_sgn = '+' if $exp_str eq '0'; # "+3e-0" -> "+3e+0"
6468              
6469 6086         37696 return $sig_sgn, $sig_str, $exp_sgn, $exp_str;
6470             }
6471              
6472             # Takes any string representing a valid decimal number and splits it into four
6473             # strings: the sign of the significand, the absolute value of the significand,
6474             # the sign of the exponent, and the absolute value of the exponent. Both the
6475             # significand and the exponent are in base 10.
6476             #
6477             # Perl accepts literals like the following. The value is 100.1.
6478             #
6479             # 1__0__.__0__1__e+0__1__ (prints "Misplaced _ in number")
6480             # 1_0.0_1e+0_1
6481             #
6482             # Strings representing decimal numbers do not allow underscores, so only the
6483             # following is valid
6484             #
6485             # "10.01e+01"
6486              
6487             sub _dec_str_to_dec_str_parts {
6488 8722     8722   15603 my $class = shift;
6489 8722         18099 my $str = shift;
6490              
6491 8722 100       67131 if ($str =~ /
6492             ^
6493              
6494             # optional leading whitespace
6495             \s*
6496              
6497             # optional sign
6498             ( [+-]? )
6499              
6500             # significand
6501             (
6502             # integer part and optional fraction part ...
6503             \d+ (?: _+ \d+ )* _*
6504             (?:
6505             \.
6506             (?: _* \d+ (?: _+ \d+ )* _* )?
6507             )?
6508             |
6509             # ... or mandatory fraction part
6510             \.
6511             \d+ (?: _+ \d+ )* _*
6512             )
6513              
6514             # optional exponent
6515             (?:
6516             [Ee]
6517             ( [+-]? )
6518             ( \d+ (?: _+ \d+ )* _* )
6519             )?
6520              
6521             # optional trailing whitespace
6522             \s*
6523              
6524             $
6525             /x)
6526             {
6527 7291         29859 return $class -> _trim_split_parts($1, $2, $3, $4);
6528             }
6529              
6530 1431         4817 return;
6531             }
6532              
6533             # Takes any string representing a valid hexadecimal number and splits it into
6534             # four strings: the sign of the significand, the absolute value of the
6535             # significand, the sign of the exponent, and the absolute value of the
6536             # exponent. The significand is in base 16, and the exponent is in base 2.
6537             #
6538             # Perl accepts literals like the following. The "x" might be a capital "X". The
6539             # value is 32.0078125.
6540             #
6541             # 0x__1__0__.0__1__p+0__1__ (prints "Misplaced _ in number")
6542             # 0x1_0.0_1p+0_1
6543             #
6544             # The CORE::hex() function does not accept floating point accepts
6545             #
6546             # "0x_1_0"
6547             # "x_1_0"
6548             # "_1_0"
6549              
6550             sub _hex_str_to_hex_str_parts {
6551 1123     1123   1895 my $class = shift;
6552 1123         1965 my $str = shift;
6553              
6554 1123 100       8084 if ($str =~ /
6555             ^
6556              
6557             # optional leading whitespace
6558             \s*
6559              
6560             # optional sign
6561             ( [+-]? )
6562              
6563             # optional hex prefix
6564             (?: 0? [Xx] _* )?
6565              
6566             # significand using the hex digits 0..9 and a..f
6567             (
6568             # integer part and optional fraction part ...
6569             [0-9a-fA-F]+ (?: _+ [0-9a-fA-F]+ )* _*
6570             (?:
6571             \.
6572             (?: _* [0-9a-fA-F]+ (?: _+ [0-9a-fA-F]+ )* _* )?
6573             )?
6574             |
6575             # ... or mandatory fraction part
6576             \.
6577             [0-9a-fA-F]+ (?: _+ [0-9a-fA-F]+ )* _*
6578             )
6579              
6580             # optional exponent (power of 2) using decimal digits
6581             (?:
6582             [Pp]
6583             ( [+-]? )
6584             ( \d+ (?: _+ \d+ )* _* )
6585             )?
6586              
6587             # optional trailing whitespace
6588             \s*
6589              
6590             $
6591             /x)
6592             {
6593 1119         4267 return $class -> _trim_split_parts($1, $2, $3, $4);
6594             }
6595              
6596 4         20 return;
6597             }
6598              
6599             # Takes any string representing a valid octal number and splits it into four
6600             # strings: the sign of the significand, the absolute value of the significand,
6601             # the sign of the exponent, and the absolute value of the exponent. The
6602             # significand is in base 8, and the exponent is in base 2.
6603              
6604             sub _oct_str_to_oct_str_parts {
6605 6     6   15 my $class = shift;
6606 6         12 my $str = shift;
6607              
6608 6 50       101 if ($str =~ /
6609             ^
6610              
6611             # optional leading whitespace
6612             \s*
6613              
6614             # optional sign
6615             ( [+-]? )
6616              
6617             # optional octal prefix
6618             (?: 0? [Oo] _* )?
6619              
6620             # significand using the octal digits 0..7
6621             (
6622             # integer part and optional fraction part ...
6623             [0-7]+ (?: _+ [0-7]+ )* _*
6624             (?:
6625             \.
6626             (?: _* [0-7]+ (?: _+ [0-7]+ )* _* )?
6627             )?
6628             |
6629             # ... or mandatory fraction part
6630             \.
6631             [0-7]+ (?: _+ [0-7]+ )* _*
6632             )
6633              
6634             # optional exponent (power of 2) using decimal digits
6635             (?:
6636             [Pp]
6637             ( [+-]? )
6638             ( \d+ (?: _+ \d+ )* _* )
6639             )?
6640              
6641             # optional trailing whitespace
6642             \s*
6643              
6644             $
6645             /x)
6646             {
6647 6         28 return $class -> _trim_split_parts($1, $2, $3, $4);
6648             }
6649              
6650 0         0 return;
6651             }
6652              
6653             # Takes any string representing a valid binary number and splits it into four
6654             # strings: the sign of the significand, the absolute value of the significand,
6655             # the sign of the exponent, and the absolute value of the exponent. The
6656             # significand is in base 2, and the exponent is in base 2.
6657              
6658             sub _bin_str_to_bin_str_parts {
6659 314     314   566 my $class = shift;
6660 314         584 my $str = shift;
6661              
6662 314 100       2713 if ($str =~ /
6663             ^
6664              
6665             # optional leading whitespace
6666             \s*
6667              
6668             # optional sign
6669             ( [+-]? )
6670              
6671             # optional binary prefix
6672             (?: 0? [Bb] _* )?
6673              
6674             # significand using the binary digits 0 and 1
6675             (
6676             # integer part and optional fraction part ...
6677             [01]+ (?: _+ [01]+ )* _*
6678             (?:
6679             \.
6680             (?: _* [01]+ (?: _+ [01]+ )* _* )?
6681             )?
6682             |
6683             # ... or mandatory fraction part
6684             \.
6685             [01]+ (?: _+ [01]+ )* _*
6686             )
6687              
6688             # optional exponent (power of 2) using decimal digits
6689             (?:
6690             [Pp]
6691             ( [+-]? )
6692             ( \d+ (?: _+ \d+ )* _* )
6693             )?
6694              
6695             # optional trailing whitespace
6696             \s*
6697              
6698             $
6699             /x)
6700             {
6701 255         1327 return $class -> _trim_split_parts($1, $2, $3, $4);
6702             }
6703              
6704 59         213 return;
6705             }
6706              
6707             # Takes any string representing a valid decimal number and splits it into four
6708             # parts: the sign of the significand, the absolute value of the significand as
6709             # a libray thingy, the sign of the exponent, and the absolute value of the
6710             # exponent as a library thingy.
6711              
6712             sub _dec_str_parts_to_flt_lib_parts {
6713 7291     7291   12431 shift; # class name
6714              
6715 7291         21524 my ($sig_sgn, $sig_str, $exp_sgn, $exp_str) = @_;
6716              
6717             # Handle zero.
6718              
6719 7291 100       18396 if ($sig_str eq '0') {
6720 2573         11994 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
6721             }
6722              
6723             # Absolute value of exponent as library "object".
6724              
6725 4718         25158 my $exp_lib = $LIB -> _new($exp_str);
6726              
6727             # If there is a dot in the significand, remove it so the significand
6728             # becomes an integer and adjust the exponent accordingly. Also remove
6729             # leading zeros which might now appear in the significand. E.g.,
6730             #
6731             # 12.345e-2 -> 12345e-5
6732             # 12.345e+2 -> 12345e-1
6733             # 0.0123e+5 -> 00123e+1 -> 123e+1
6734              
6735 4718         12321 my $idx = index $sig_str, '.';
6736 4718 100       13222 if ($idx >= 0) {
6737 3437         10148 substr($sig_str, $idx, 1) = '';
6738              
6739             # delta = length - index
6740 3437         10719 my $delta = $LIB -> _new(CORE::length($sig_str));
6741 3437         10432 $delta = $LIB -> _sub($delta, $LIB -> _new($idx));
6742              
6743             # exponent - delta
6744 3437         21056 ($exp_lib, $exp_sgn) = $LIB -> _ssub($exp_lib, $exp_sgn, $delta, '+');
6745              
6746 3437         13334 $sig_str =~ s/^0+//;
6747             }
6748              
6749             # If there are trailing zeros in the significand, remove them and
6750             # adjust the exponent. E.g.,
6751             #
6752             # 12340e-5 -> 1234e-4
6753             # 12340e-1 -> 1234e0
6754             # 12340e+3 -> 1234e4
6755              
6756 4718 100       19493 if ($sig_str =~ s/(0+)\z//) {
6757 900         2380 my $len = CORE::length($1);
6758 900         3187 ($exp_lib, $exp_sgn) =
6759             $LIB -> _sadd($exp_lib, $exp_sgn, $LIB -> _new($len), '+');
6760             }
6761              
6762             # At this point, the significand is empty or an integer with no trailing
6763             # zeros. The exponent is in base 10.
6764              
6765 4718 50       13713 unless (CORE::length $sig_str) {
6766 0         0 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
6767             }
6768              
6769             # Absolute value of significand as library "object".
6770              
6771 4718         15987 my $sig_lib = $LIB -> _new($sig_str);
6772              
6773 4718         39222 return $sig_sgn, $sig_lib, $exp_sgn, $exp_lib;
6774             }
6775              
6776             # Takes any string representing a valid binary number and splits it into four
6777             # parts: the sign of the significand, the absolute value of the significand as
6778             # a libray thingy, the sign of the exponent, and the absolute value of the
6779             # exponent as a library thingy.
6780              
6781             sub _bin_str_parts_to_flt_lib_parts {
6782 1380     1380   3540 shift; # class name
6783              
6784 1380         4281 my ($sig_sgn, $sig_str, $exp_sgn, $exp_str, $bpc) = @_;
6785 1380         7105 my $bpc_lib = $LIB -> _new($bpc);
6786              
6787             # Handle zero.
6788              
6789 1380 100       5490 if ($sig_str eq '0') {
6790 12         47 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
6791             }
6792              
6793             # Absolute value of exponent as library "object".
6794              
6795 1368         3386 my $exp_lib = $LIB -> _new($exp_str);
6796              
6797             # If there is a dot in the significand, remove it so the significand
6798             # becomes an integer and adjust the exponent accordingly. Also remove
6799             # leading zeros which might now appear in the significand. E.g., with
6800             # hexadecimal numbers
6801             #
6802             # 12.345p-2 -> 12345p-14
6803             # 12.345p+2 -> 12345p-10
6804             # 0.0123p+5 -> 00123p-11 -> 123p-11
6805              
6806 1368         3015 my $idx = index $sig_str, '.';
6807 1368 100       3201 if ($idx >= 0) {
6808 3         12 substr($sig_str, $idx, 1) = '';
6809              
6810             # delta = (length - index) * bpc
6811 3         10 my $delta = $LIB -> _new(CORE::length($sig_str));
6812 3         13 $delta = $LIB -> _sub($delta, $LIB -> _new($idx));
6813 3 100       21 $delta = $LIB -> _mul($delta, $bpc_lib) if $bpc != 1;
6814              
6815             # exponent - delta
6816 3         18 ($exp_lib, $exp_sgn) = $LIB -> _ssub($exp_lib, $exp_sgn, $delta, '+');
6817              
6818 3         11 $sig_str =~ s/^0+//;
6819             }
6820              
6821             # If there are trailing zeros in the significand, remove them and
6822             # adjust the exponent accordingly. E.g., with hexadecimal numbers
6823             #
6824             # 12340p-5 -> 1234p-1
6825             # 12340p-1 -> 1234p+3
6826             # 12340p+3 -> 1234p+7
6827              
6828 1368 100       9159 if ($sig_str =~ s/(0+)\z//) {
6829              
6830             # delta = length * bpc
6831 248         988 my $delta = $LIB -> _new(CORE::length($1));
6832 248 100       5326 $delta = $LIB -> _mul($delta, $bpc_lib) if $bpc != 1;
6833              
6834             # exponent + delta
6835 248         1318 ($exp_lib, $exp_sgn) = $LIB -> _sadd($exp_lib, $exp_sgn, $delta, '+');
6836             }
6837              
6838             # At this point, the significand is empty or an integer with no leading
6839             # or trailing zeros. The exponent is in base 2.
6840              
6841 1368 50       3556 unless (CORE::length $sig_str) {
6842 0         0 return '+', $LIB -> _zero(), '+', $LIB -> _zero();
6843             }
6844              
6845             # Absolute value of significand as library "object".
6846              
6847 1368 50       9082 my $sig_lib = $bpc == 1 ? $LIB -> _from_bin('0b' . $sig_str)
    100          
    100          
6848             : $bpc == 3 ? $LIB -> _from_oct('0' . $sig_str)
6849             : $bpc == 4 ? $LIB -> _from_hex('0x' . $sig_str)
6850             : die "internal error: invalid exponent multiplier";
6851              
6852             # If the exponent (in base 2) is positive or zero ...
6853              
6854 1368 100       3458 if ($exp_sgn eq '+') {
6855              
6856 1367 100       4608 if (!$LIB -> _is_zero($exp_lib)) {
6857              
6858             # Multiply significand by 2 raised to the exponent.
6859              
6860 249         1024 my $p = $LIB -> _pow($LIB -> _two(), $exp_lib);
6861 249         890 $sig_lib = $LIB -> _mul($sig_lib, $p);
6862 249         803 $exp_lib = $LIB -> _zero();
6863             }
6864             }
6865              
6866             # ... else if the exponent is negative ...
6867              
6868             else {
6869              
6870             # Rather than dividing the significand by 2 raised to the absolute
6871             # value of the exponent, multiply the significand by 5 raised to the
6872             # absolute value of the exponent and let the exponent be in base 10:
6873             #
6874             # a * 2^(-b) = a * 5^b * 10^(-b) = c * 10^(-b), where c = a * 5^b
6875              
6876 1         5 my $p = $LIB -> _pow($LIB -> _new("5"), $exp_lib);
6877 1         33 $sig_lib = $LIB -> _mul($sig_lib, $p);
6878             }
6879              
6880             # Adjust for the case when the conversion to decimal introduced trailing
6881             # zeros in the significand.
6882              
6883 1368         4567 my $n = $LIB -> _zeros($sig_lib);
6884 1368 100       3305 if ($n) {
6885 213         773 $n = $LIB -> _new($n);
6886 213         980 $sig_lib = $LIB -> _rsft($sig_lib, $n, 10);
6887 213         949 ($exp_lib, $exp_sgn) = $LIB -> _sadd($exp_lib, $exp_sgn, $n, '+');
6888             }
6889              
6890 1368         11138 return $sig_sgn, $sig_lib, $exp_sgn, $exp_lib;
6891             }
6892              
6893             # Takes any string representing a valid hexadecimal number and splits it into
6894             # four parts: the sign of the significand, the absolute value of the
6895             # significand as a libray thingy, the sign of the exponent, and the absolute
6896             # value of the exponent as a library thingy.
6897              
6898             sub _hex_str_to_flt_lib_parts {
6899 1123     1123   2351 my $class = shift;
6900 1123         2157 my $str = shift;
6901 1123 100       4016 if (my @parts = $class -> _hex_str_to_hex_str_parts($str)) {
6902             # 4 bits pr. chr
6903 1119         3580 return $class -> _bin_str_parts_to_flt_lib_parts(@parts, 4);
6904             }
6905 4         88 return;
6906             }
6907              
6908             # Takes any string representing a valid octal number and splits it into four
6909             # parts: the sign of the significand, the absolute value of the significand as
6910             # a libray thingy, the sign of the exponent, and the absolute value of the
6911             # exponent as a library thingy.
6912              
6913             sub _oct_str_to_flt_lib_parts {
6914 6     6   29 my $class = shift;
6915 6         104 my $str = shift;
6916 6 50       35 if (my @parts = $class -> _oct_str_to_oct_str_parts($str)) {
6917             # 3 bits pr. chr
6918 6         29 return $class -> _bin_str_parts_to_flt_lib_parts(@parts, 3);
6919             }
6920 0         0 return;
6921             }
6922              
6923             # Takes any string representing a valid binary number and splits it into four
6924             # parts: the sign of the significand, the absolute value of the significand as
6925             # a libray thingy, the sign of the exponent, and the absolute value of the
6926             # exponent as a library thingy.
6927              
6928             sub _bin_str_to_flt_lib_parts {
6929 314     314   769 my $class = shift;
6930 314         599 my $str = shift;
6931 314 100       1178 if (my @parts = $class -> _bin_str_to_bin_str_parts($str)) {
6932             # 1 bit pr. chr
6933 255         961 return $class -> _bin_str_parts_to_flt_lib_parts(@parts, 1);
6934             }
6935 59         404 return;
6936             }
6937              
6938             # Decimal string is split into the sign of the signficant, the absolute value
6939             # of the significand as library thingy, the sign of the exponent, and the
6940             # absolute value of the exponent as a a library thingy.
6941              
6942             sub _dec_str_to_flt_lib_parts {
6943 8722     8722   18623 my $class = shift;
6944 8722         17185 my $str = shift;
6945 8722 100       31921 if (my @parts = $class -> _dec_str_to_dec_str_parts($str)) {
6946 7291         26074 return $class -> _dec_str_parts_to_flt_lib_parts(@parts);
6947             }
6948 1431         9025 return;
6949             }
6950              
6951             # Decimal string to a string using decimal floating point notation.
6952              
6953             sub dec_str_to_dec_flt_str {
6954 0     0 1 0 my $class = shift;
6955 0         0 my $str = shift;
6956 0 0       0 if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
6957 0         0 return $class -> _flt_lib_parts_to_flt_str(@parts);
6958             }
6959 0         0 return;
6960             }
6961              
6962             # Hexdecimal string to a string using decimal floating point notation.
6963              
6964             sub hex_str_to_dec_flt_str {
6965 0     0 1 0 my $class = shift;
6966 0         0 my $str = shift;
6967 0 0       0 if (my @parts = $class -> _hex_str_to_flt_lib_parts($str)) {
6968 0         0 return $class -> _flt_lib_parts_to_flt_str(@parts);
6969             }
6970 0         0 return;
6971             }
6972              
6973             # Octal string to a string using decimal floating point notation.
6974              
6975             sub oct_str_to_dec_flt_str {
6976 0     0 1 0 my $class = shift;
6977 0         0 my $str = shift;
6978 0 0       0 if (my @parts = $class -> _oct_str_to_flt_lib_parts($str)) {
6979 0         0 return $class -> _flt_lib_parts_to_flt_str(@parts);
6980             }
6981 0         0 return;
6982             }
6983              
6984             # Binary string to a string decimal floating point notation.
6985              
6986             sub bin_str_to_dec_flt_str {
6987 0     0 1 0 my $class = shift;
6988 0         0 my $str = shift;
6989 0 0       0 if (my @parts = $class -> _bin_str_to_flt_lib_parts($str)) {
6990 0         0 return $class -> _flt_lib_parts_to_flt_str(@parts);
6991             }
6992 0         0 return;
6993             }
6994              
6995             # Decimal string to decimal notation (no exponent).
6996              
6997             sub dec_str_to_dec_str {
6998 0     0 1 0 my $class = shift;
6999 0         0 my $str = shift;
7000 0 0       0 if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
7001 0         0 return $class -> _flt_lib_parts_to_dec_str(@parts);
7002             }
7003 0         0 return;
7004             }
7005              
7006             # Hexdecimal string to decimal notation (no exponent).
7007              
7008             sub hex_str_to_dec_str {
7009 0     0 1 0 my $class = shift;
7010 0         0 my $str = shift;
7011 0 0       0 if (my @parts = $class -> _dec_str_to_flt_lib_parts($str)) {
7012 0         0 return $class -> _flt_lib_parts_to_dec_str(@parts);
7013             }
7014 0         0 return;
7015             }
7016              
7017             # Octal string to decimal notation (no exponent).
7018              
7019             sub oct_str_to_dec_str {
7020 0     0 1 0 my $class = shift;
7021 0         0 my $str = shift;
7022 0 0       0 if (my @parts = $class -> _oct_str_to_flt_lib_parts($str)) {
7023 0         0 return $class -> _flt_lib_parts_to_dec_str(@parts);
7024             }
7025 0         0 return;
7026             }
7027              
7028             # Binary string to decimal notation (no exponent).
7029              
7030             sub bin_str_to_dec_str {
7031 0     0 1 0 my $class = shift;
7032 0         0 my $str = shift;
7033 0 0       0 if (my @parts = $class -> _bin_str_to_flt_lib_parts($str)) {
7034 0         0 return $class -> _flt_lib_parts_to_dec_str(@parts);
7035             }
7036 0         0 return;
7037             }
7038              
7039             sub _flt_lib_parts_to_flt_str {
7040 0     0   0 my $class = shift;
7041 0         0 my @parts = @_;
7042 0         0 return $parts[0] . $LIB -> _str($parts[1])
7043             . 'e' . $parts[2] . $LIB -> _str($parts[3]);
7044             }
7045              
7046             sub _flt_lib_parts_to_dec_str {
7047 0     0   0 my $class = shift;
7048 0         0 my @parts = @_;
7049              
7050             # The number is an integer iff the exponent is non-negative.
7051              
7052 0 0       0 if ($parts[2] eq '+') {
7053 0         0 my $str = $parts[0]
7054             . $LIB -> _str($LIB -> _lsft($parts[1], $parts[3], 10));
7055 0         0 return $str;
7056             }
7057              
7058             # If it is not an integer, add a decimal point.
7059              
7060             else {
7061 0         0 my $mant = $LIB -> _str($parts[1]);
7062 0         0 my $mant_len = CORE::length($mant);
7063 0         0 my $expo = $LIB -> _num($parts[3]);
7064 0         0 my $len_cmp = $mant_len <=> $expo;
7065 0 0       0 if ($len_cmp <= 0) {
7066 0         0 return $parts[0] . '0.' . '0' x ($expo - $mant_len) . $mant;
7067             } else {
7068 0         0 substr $mant, $mant_len - $expo, 0, '.';
7069 0         0 return $parts[0] . $mant;
7070             }
7071             }
7072             }
7073              
7074             # Takes four arguments, the sign of the significand, the absolute value of the
7075             # significand as a libray thingy, the sign of the exponent, and the absolute
7076             # value of the exponent as a library thingy, and returns three parts: the sign
7077             # of the rational number, the absolute value of the numerator as a libray
7078             # thingy, and the absolute value of the denominator as a library thingy.
7079             #
7080             # For example, to convert data representing the value "+12e-2", then
7081             #
7082             # $sm = "+";
7083             # $m = $LIB -> _new("12");
7084             # $se = "-";
7085             # $e = $LIB -> _new("2");
7086             # ($sr, $n, $d) = $class -> _flt_lib_parts_to_rat_lib_parts($sm, $m, $se, $e);
7087             #
7088             # returns data representing the same value written as the fraction "+3/25"
7089             #
7090             # $sr = "+"
7091             # $n = $LIB -> _new("3");
7092             # $d = $LIB -> _new("12");
7093              
7094             sub _flt_lib_parts_to_rat_lib_parts {
7095 1030     1030   1534 my $self = shift;
7096 1030         2289 my ($msgn, $mabs, $esgn, $eabs) = @_;
7097              
7098 1030 50       2150 if ($esgn eq '-') { # "12e-2" -> "12/100" -> "3/25"
    0          
7099 1030         3198 my $num_lib = $LIB -> _copy($mabs);
7100 1030         3130 my $den_lib = $LIB -> _1ex($LIB -> _num($eabs));
7101 1030         2622 my $gcd_lib = $LIB -> _gcd($LIB -> _copy($num_lib), $den_lib);
7102 1030         2663 $num_lib = $LIB -> _div($LIB -> _copy($num_lib), $gcd_lib);
7103 1030         2471 $den_lib = $LIB -> _div($den_lib, $gcd_lib);
7104 1030         4091 return $msgn, $num_lib, $den_lib;
7105             }
7106              
7107             elsif (!$LIB -> _is_zero($eabs)) { # "12e+2" -> "1200" -> "1200/1"
7108 0         0 return $msgn, $LIB -> _lsft($LIB -> _copy($mabs), $eabs, 10),
7109             $LIB -> _one();
7110             }
7111              
7112             else { # "12e+0" -> "12" -> "12/1"
7113 0         0 return $msgn, $mabs, $LIB -> _one();
7114             }
7115             }
7116              
7117             # Add the function _register_callback() to Math::BigInt. It is provided for
7118             # backwards compabibility so that old version of Math::BigRat etc. don't
7119             # complain about missing it.
7120              
7121       0     sub _register_callback { }
7122              
7123             ###############################################################################
7124             # Other methods.
7125             ###############################################################################
7126              
7127             sub objectify {
7128             # Convert strings and "foreign objects" to the objects we want.
7129              
7130             # The first argument, $count, is the number of following arguments that
7131             # objectify() looks at and converts to objects. The first is a classname.
7132             # If the given count is 0, all arguments will be used.
7133              
7134             # After the count is read, objectify obtains the name of the class to which
7135             # the following arguments are converted. If the second argument is a
7136             # reference, use the reference type as the class name. Otherwise, if it is
7137             # a string that looks like a class name, use that. Otherwise, use $class.
7138              
7139             # Caller: Gives us:
7140             #
7141             # $x->badd(1); => ref x, scalar y
7142             # Class->badd(1, 2); => classname x (scalar), scalar x, scalar y
7143             # Class->badd(Class->(1), 2); => classname x (scalar), ref x, scalar y
7144             # Math::BigInt::badd(1, 2); => scalar x, scalar y
7145              
7146             # A shortcut for the common case $x->unary_op(), in which case the argument
7147             # list is (0, $x) or (1, $x).
7148              
7149 6024 100 100 6024 0 43409 return (ref($_[1]), $_[1]) if @_ == 2 && ($_[0] || 0) == 1 && ref($_[1]);
      100        
      66        
7150              
7151             # Check the context.
7152              
7153 5819 50       14552 unless (wantarray) {
7154 0         0 croak(__PACKAGE__ . "::objectify() needs list context");
7155             }
7156              
7157             # Get the number of arguments to objectify.
7158              
7159 5819         13227 my $count = shift;
7160              
7161             # Initialize the output array.
7162              
7163 5819         17176 my @a = @_;
7164              
7165             # If the first argument is a reference, use that reference type as our
7166             # class name. Otherwise, if the first argument looks like a class name,
7167             # then use that as our class name. Otherwise, use the default class name.
7168              
7169 5819         9690 my $class;
7170 5819 100       19293 if (ref($a[0])) { # reference?
    100          
7171 4395         8914 $class = ref($a[0]);
7172             } elsif ($a[0] =~ /^[A-Z].*::/) { # string with class name?
7173 1412         3390 $class = shift @a;
7174             } else {
7175 12         30 $class = __PACKAGE__; # default class name
7176             }
7177              
7178 5819   66     17888 $count ||= @a;
7179 5819         15041 unshift @a, $class;
7180              
7181             # What we upgrade to, if anything. Note that we need the whole upgrade
7182             # chain, since there might be multiple levels of upgrading. E.g., class A
7183             # upgrades to class B, which upgrades to class C. Delay getting the chain
7184             # until we actually need it.
7185              
7186 5819         10859 my @upg = ();
7187 5819         9584 my $have_upgrade_chain = 0;
7188              
7189             # Disable downgrading, because Math::BigFloat -> foo('1.0', '2.0') needs
7190             # floats.
7191              
7192 5819         19088 my $dng = $class -> downgrade();
7193 5819         18008 $class -> downgrade(undef);
7194              
7195 5819         18335 ARG: for my $i (1 .. $count) {
7196              
7197 10772         21842 my $ref = ref $a[$i];
7198              
7199             # Perl scalars are fed to the appropriate constructor.
7200              
7201 10772 100       23684 unless ($ref) {
7202 5103         17755 $a[$i] = $class -> new($a[$i]);
7203 5103         23142 next;
7204             }
7205              
7206             # If it is an object of the right class, all is fine.
7207              
7208 5669 100       22806 next if $ref -> isa($class);
7209              
7210             # Upgrading is OK, so skip further tests if the argument is upgraded,
7211             # but first get the whole upgrade chain if we haven't got it yet.
7212              
7213 236 100       654 unless ($have_upgrade_chain) {
7214 181         309 my $cls = $class;
7215 181         525 my $upg = $cls -> upgrade();
7216 181         776 while (defined $upg) {
7217 9 50       41 last if $upg eq $cls;
7218 9         129 push @upg, $upg;
7219 9         24 $cls = $upg;
7220 9         33 $upg = $cls -> upgrade();
7221             }
7222 181         362 $have_upgrade_chain = 1;
7223             }
7224              
7225 236         571 for my $upg (@upg) {
7226 9 50       30 next ARG if $ref -> isa($upg);
7227             }
7228              
7229             # See if we can call one of the as_xxx() methods. We don't know whether
7230             # the as_xxx() method returns an object or a scalar, so re-check
7231             # afterwards.
7232              
7233 227         412 my $recheck = 0;
7234              
7235 227 100       918 if ($class -> isa('Math::BigInt')) {
    100          
    50          
7236 2 50       19 if ($a[$i] -> can('as_int')) {
    0          
7237 2         8 $a[$i] = $a[$i] -> as_int();
7238 2         6 $recheck = 1;
7239             } elsif ($a[$i] -> can('as_number')) {
7240 0         0 $a[$i] = $a[$i] -> as_number();
7241 0         0 $recheck = 1;
7242             }
7243             }
7244              
7245             elsif ($class -> isa('Math::BigRat')) {
7246 16 50       88 if ($a[$i] -> can('as_rat')) {
7247 16         46 $a[$i] = $a[$i] -> as_rat();
7248 16         45 $recheck = 1;
7249             }
7250             }
7251              
7252             elsif ($class -> isa('Math::BigFloat')) {
7253 209 50       987 if ($a[$i] -> can('as_float')) {
7254 209         577 $a[$i] = $a[$i] -> as_float();
7255 209         464 $recheck = 1;
7256             }
7257             }
7258              
7259             # If we called one of the as_xxx() methods, recheck.
7260              
7261 227 50       667 if ($recheck) {
7262 227         534 $ref = ref($a[$i]);
7263              
7264             # Perl scalars are fed to the appropriate constructor.
7265              
7266 227 50       551 unless ($ref) {
7267 0         0 $a[$i] = $class -> new($a[$i]);
7268 0         0 next;
7269             }
7270              
7271             # If it is an object of the right class, all is fine.
7272              
7273 227 100       708 next if $ref -> isa($class);
7274             }
7275              
7276             # Last resort.
7277              
7278 14         63 $a[$i] = $class -> new($a[$i]);
7279             }
7280              
7281             # Restore the downgrading.
7282              
7283 5819         20051 $class -> downgrade($dng);
7284              
7285 5819         26449 return @a;
7286             }
7287              
7288             sub import {
7289 185     185   7488 my $class = shift;
7290 185         346 $IMPORT++; # remember we did import()
7291 185         352 my @a; # unrecognized arguments
7292              
7293 185         577 while (@_) {
7294 33         71 my $param = shift;
7295              
7296             # Enable overloading of constants.
7297              
7298 33 100       109 if ($param eq ':constant') {
7299             overload::constant
7300              
7301             integer => sub {
7302 2     2   13 $class -> new(shift);
7303             },
7304              
7305             float => sub {
7306 0     0   0 $class -> new(shift);
7307             },
7308              
7309             binary => sub {
7310             # E.g., a literal 0377 shall result in an object whose
7311             # value is decimal 255, but new("0377") returns decimal
7312             # 377.
7313 0 0   0   0 return $class -> from_oct($_[0]) if $_[0] =~ /^0_*[0-7]/;
7314 0         0 $class -> new(shift);
7315 1         12 };
7316 1         52 next;
7317             }
7318              
7319             # Upgrading.
7320              
7321 32 100       102 if ($param eq 'upgrade') {
7322 4         19 $class -> upgrade(shift);
7323 4         12 next;
7324             }
7325              
7326             # Downgrading.
7327              
7328 28 50       78 if ($param eq 'downgrade') {
7329 0         0 $class -> downgrade(shift);
7330 0         0 next;
7331             }
7332              
7333             # Accuracy.
7334              
7335 28 50       101 if ($param eq 'accuracy') {
7336 0         0 $class -> accuracy(shift);
7337 0         0 next;
7338             }
7339              
7340             # Precision.
7341              
7342 28 50       78 if ($param eq 'precision') {
7343 0         0 $class -> precision(shift);
7344 0         0 next;
7345             }
7346              
7347             # Rounding mode.
7348              
7349 28 50       79 if ($param eq 'round_mode') {
7350 0         0 $class -> round_mode(shift);
7351 0         0 next;
7352             }
7353              
7354             # Fall-back accuracy.
7355              
7356 28 50       81 if ($param eq 'div_scale') {
7357 0         0 $class -> div_scale(shift);
7358 0         0 next;
7359             }
7360              
7361             # Backend library.
7362              
7363 28 100       193 if ($param =~ /^(lib|try|only)\z/) {
7364             # try => 0 (no warn if unavailable module)
7365             # lib => 1 (warn on fallback)
7366             # only => 2 (die on fallback)
7367              
7368             # Get the list of user-specified libraries.
7369              
7370 24 50       74 croak "Library argument for import parameter '$param' is missing"
7371             unless @_;
7372 24         131 my $libs = shift;
7373 24 50       74 croak "Library argument for import parameter '$param' is undefined"
7374             unless defined($libs);
7375              
7376             # Check and clean up the list of user-specified libraries.
7377              
7378 24         43 my @libs;
7379 24         103 for my $lib (split /,/, $libs) {
7380 24         87 $lib =~ s/^\s+//;
7381 24         82 $lib =~ s/\s+$//;
7382              
7383 24 50       101 if ($lib =~ /[^a-zA-Z0-9_:]/) {
7384 0         0 carp "Library name '$lib' contains invalid characters";
7385 0         0 next;
7386             }
7387              
7388 24 50       90 if (! CORE::length $lib) {
7389 0         0 carp "Library name is empty";
7390 0         0 next;
7391             }
7392              
7393 24 100       151 $lib = "Math::BigInt::$lib" if $lib !~ /^Math::BigInt::/i;
7394              
7395             # If a library has already been loaded, that is OK only if the
7396             # requested library is identical to the loaded one.
7397              
7398 24 100       73 if (defined($LIB)) {
7399 8 50       30 if ($lib ne $LIB) {
7400             #carp "Library '$LIB' has already been loaded, so",
7401             # " ignoring requested library '$lib'";
7402             }
7403 8         23 next;
7404             }
7405              
7406 16         53 push @libs, $lib;
7407             }
7408              
7409 24 100       142 next if defined $LIB;
7410              
7411 16 50       49 croak "Library list contains no valid libraries" unless @libs;
7412              
7413             # Try to load the specified libraries, if any.
7414              
7415 16         56 for (my $i = 0 ; $i <= $#libs ; $i++) {
7416 16         36 my $lib = $libs[$i];
7417 16         1606 eval "require $lib";
7418 16 50       2726 unless ($@) {
7419 16         47 $LIB = $lib;
7420 16         48 last;
7421             }
7422             }
7423              
7424 16 50       148 next if defined $LIB;
7425              
7426             # No library has been loaded, and none of the requested libraries
7427             # could be loaded, and fallback and the user doesn't allow
7428             # fallback.
7429              
7430 0 0       0 if ($param eq 'only') {
7431 0         0 croak "Couldn't load the specified math lib(s) ",
7432             join(", ", map "'$_'", @libs),
7433             ", and fallback to '$DEFAULT_LIB' is not allowed";
7434             }
7435              
7436             # No library has been loaded, and none of the requested libraries
7437             # could be loaded, but the user accepts the use of a fallback
7438             # library, so try to load it.
7439              
7440 0         0 eval "require $DEFAULT_LIB";
7441 0 0       0 if ($@) {
7442 0         0 croak "Couldn't load the specified math lib(s) ",
7443             join(", ", map "'$_'", @libs),
7444             ", not even the fallback lib '$DEFAULT_LIB'";
7445             }
7446              
7447             # The fallback library was successfully loaded, but the user
7448             # might want to know that we are using the fallback.
7449              
7450 0 0       0 if ($param eq 'lib') {
7451 0         0 carp "Couldn't load the specified math lib(s) ",
7452             join(", ", map "'$_'", @libs),
7453             ", so using fallback lib '$DEFAULT_LIB'";
7454             }
7455              
7456 0         0 next;
7457             }
7458              
7459             # Unrecognized parameter.
7460              
7461 4         11 push @a, $param;
7462             }
7463              
7464             # Any non-':constant' stuff is handled by our parent, Exporter
7465              
7466 185         6314 $class -> SUPER::import(@a); # for subclasses
7467 185 100       757 $class -> export_to_level(1, $class, @a) if @a; # need this, too
7468              
7469             # We might not have loaded any backend library yet, either because the user
7470             # didn't specify any, or because the specified libraries failed to load and
7471             # the user allows the use of a fallback library.
7472              
7473 185 100       16872 unless (defined $LIB) {
7474 34         3242 eval "require $DEFAULT_LIB";
7475 34 50       312 if ($@) {
7476 0         0 croak "No lib specified, and couldn't load the default",
7477             " lib '$DEFAULT_LIB'";
7478             }
7479 34         3033 $LIB = $DEFAULT_LIB;
7480             }
7481              
7482             # import done
7483             }
7484              
7485             1;
7486              
7487             __END__