1package bigrat;
2
3use strict;
4use warnings;
5
6use Carp qw< carp croak >;
7
8our $VERSION = '0.66';
9
10use Exporter;
11our @ISA            = qw( Exporter );
12our @EXPORT_OK      = qw( PI e bpi bexp hex oct );
13our @EXPORT         = qw( inf NaN );
14
15use overload;
16
17my $obj_class = "Math::BigRat";
18
19##############################################################################
20
21sub accuracy {
22    my $self = shift;
23    $obj_class -> accuracy(@_);
24}
25
26sub precision {
27    my $self = shift;
28    $obj_class -> precision(@_);
29}
30
31sub round_mode {
32    my $self = shift;
33    $obj_class -> round_mode(@_);
34}
35
36sub div_scale {
37    my $self = shift;
38    $obj_class -> div_scale(@_);
39}
40
41sub in_effect {
42    my $level = shift || 0;
43    my $hinthash = (caller($level))[10];
44    $hinthash->{bigrat};
45}
46
47sub _float_constant {
48    my $str = shift;
49
50    # See if we can convert the input string to a string using a normalized form
51    # consisting of the significand as a signed integer, the character "e", and
52    # the exponent as a signed integer, e.g., "+0e+0", "+314e-2", and "-1e+3".
53
54    my $nstr;
55
56    if (
57        # See if it is an octal number. An octal number like '0377' is also
58        # accepted by the functions parsing decimal and hexadecimal numbers, so
59        # handle octal numbers before decimal and hexadecimal numbers.
60
61        $str =~ /^0(?:[Oo]|_*[0-7])/ and
62        $nstr = Math::BigInt -> oct_str_to_dec_flt_str($str)
63
64          or
65
66        # See if it is decimal number.
67
68        $nstr = Math::BigInt -> dec_str_to_dec_flt_str($str)
69
70          or
71
72        # See if it is a hexadecimal number. Every hexadecimal number has a
73        # prefix, but the functions parsing numbers don't require it, so check
74        # to see if it actually is a hexadecimal number.
75
76        $str =~ /^0[Xx]/ and
77        $nstr = Math::BigInt -> hex_str_to_dec_flt_str($str)
78
79          or
80
81        # See if it is a binary numbers. Every binary number has a prefix, but
82        # the functions parsing numbers don't require it, so check to see if it
83        # actually is a binary number.
84
85        $str =~ /^0[Bb]/ and
86        $nstr = Math::BigInt -> bin_str_to_dec_flt_str($str))
87    {
88        return $obj_class -> new($nstr);
89    }
90
91    # If we get here, there is a bug in the code above this point.
92
93    warn "Internal error: unable to handle literal constant '$str'.",
94      " This is a bug, so please report this to the module author.";
95    return $obj_class -> bnan();
96}
97
98#############################################################################
99# the following two routines are for "use bigrat qw/hex oct/;":
100
101use constant LEXICAL => $] > 5.009004;
102
103# Internal function with the same semantics as CORE::hex(). This function is
104# not used directly, but rather by other front-end functions.
105
106sub _hex_core {
107    my $str = shift;
108
109    # Strip off, clean, and parse as much as we can from the beginning.
110
111    my $x;
112    if ($str =~ s/ ^ ( 0? [xX] )? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) {
113        my $chrs = $2;
114        $chrs =~ tr/_//d;
115        $chrs = '0' unless CORE::length $chrs;
116        $x = $obj_class -> from_hex($chrs);
117    } else {
118        $x = $obj_class -> bzero();
119    }
120
121    # Warn about trailing garbage.
122
123    if (CORE::length($str)) {
124        require Carp;
125        Carp::carp(sprintf("Illegal hexadecimal digit '%s' ignored",
126                           substr($str, 0, 1)));
127    }
128
129    return $x;
130}
131
132# Internal function with the same semantics as CORE::oct(). This function is
133# not used directly, but rather by other front-end functions.
134
135sub _oct_core {
136    my $str = shift;
137
138    $str =~ s/^\s*//;
139
140    # Hexadecimal input.
141
142    return _hex_core($str) if $str =~ /^0?[xX]/;
143
144    my $x;
145
146    # Binary input.
147
148    if ($str =~ /^0?[bB]/) {
149
150        # Strip off, clean, and parse as much as we can from the beginning.
151
152        if ($str =~ s/ ^ ( 0? [bB] )? ( [01]* ( _ [01]+ )* ) //x) {
153            my $chrs = $2;
154            $chrs =~ tr/_//d;
155            $chrs = '0' unless CORE::length $chrs;
156            $x = $obj_class -> from_bin($chrs);
157        }
158
159        # Warn about trailing garbage.
160
161        if (CORE::length($str)) {
162            require Carp;
163            Carp::carp(sprintf("Illegal binary digit '%s' ignored",
164                               substr($str, 0, 1)));
165        }
166
167        return $x;
168    }
169
170    # Octal input. Strip off, clean, and parse as much as we can from the
171    # beginning.
172
173    if ($str =~ s/ ^ ( 0? [oO] )? ( [0-7]* ( _ [0-7]+ )* ) //x) {
174        my $chrs = $2;
175        $chrs =~ tr/_//d;
176        $chrs = '0' unless CORE::length $chrs;
177        $x = $obj_class -> from_oct($chrs);
178    }
179
180    # Warn about trailing garbage. CORE::oct() only warns about 8 and 9, but it
181    # is more helpful to warn about all invalid digits.
182
183    if (CORE::length($str)) {
184        require Carp;
185        Carp::carp(sprintf("Illegal octal digit '%s' ignored",
186                           substr($str, 0, 1)));
187    }
188
189    return $x;
190}
191
192{
193    my $proto = LEXICAL ? '_' : ';$';
194    eval '
195sub hex(' . $proto . ') {' . <<'.';
196    my $str = @_ ? $_[0] : $_;
197    _hex_core($str);
198}
199.
200
201    eval '
202sub oct(' . $proto . ') {' . <<'.';
203    my $str = @_ ? $_[0] : $_;
204    _oct_core($str);
205}
206.
207}
208
209#############################################################################
210# the following two routines are for Perl 5.9.4 or later and are lexical
211
212my ($prev_oct, $prev_hex, $overridden);
213
214if (LEXICAL) { eval <<'.' }
215sub _hex(_) {
216    my $hh = (caller 0)[10];
217    return $$hh{bigrat}   ? bigrat::_hex_core($_[0])
218         : $$hh{bigfloat} ? bigfloat::_hex_core($_[0])
219         : $$hh{bigint}   ? bigint::_hex_core($_[0])
220         : $prev_hex      ? &$prev_hex($_[0])
221         : CORE::hex($_[0]);
222}
223
224sub _oct(_) {
225    my $hh = (caller 0)[10];
226    return $$hh{bigrat}   ? bigrat::_oct_core($_[0])
227         : $$hh{bigfloat} ? bigfloat::_oct_core($_[0])
228         : $$hh{bigint}   ? bigint::_oct_core($_[0])
229         : $prev_oct      ? &$prev_oct($_[0])
230         : CORE::oct($_[0]);
231}
232.
233
234sub _override {
235    return if $overridden;
236    $prev_oct = *CORE::GLOBAL::oct{CODE};
237    $prev_hex = *CORE::GLOBAL::hex{CODE};
238    no warnings 'redefine';
239    *CORE::GLOBAL::oct = \&_oct;
240    *CORE::GLOBAL::hex = \&_hex;
241    $overridden = 1;
242}
243
244sub unimport {
245    $^H{bigrat} = undef;        # no longer in effect
246    overload::remove_constant('binary', '', 'float', '', 'integer');
247}
248
249sub import {
250    my $class = shift;
251
252    $^H{bigrat}   = 1;                          # we are in effect
253    $^H{bigint}   = undef;
254    $^H{bigfloat} = undef;
255
256    # for newer Perls always override hex() and oct() with a lexical version:
257    if (LEXICAL) {
258        _override();
259    }
260
261    my @import = ();
262    my @a = ();                         # unrecognized arguments
263    my $ver;                            # version?
264
265    while (@_) {
266        my $param = shift;
267
268        # Accuracy.
269
270        if ($param =~ /^a(ccuracy)?$/) {
271            push @import, 'accuracy', shift();
272            next;
273        }
274
275        # Precision.
276
277        if ($param =~ /^p(recision)?$/) {
278            push @import, 'precision', shift();
279            next;
280        }
281
282        # Rounding mode.
283
284        if ($param eq 'round_mode') {
285            push @import, 'round_mode', shift();
286            next;
287        }
288
289        # Backend library.
290
291        if ($param =~ /^(l|lib|try|only)$/) {
292            push @import, $param eq 'l' ? 'lib' : $param;
293            push @import, shift() if @_;
294            next;
295        }
296
297        if ($param =~ /^(v|version)$/) {
298            $ver = 1;
299            next;
300        }
301
302        if ($param =~ /^(t|trace)$/) {
303            $obj_class .= "::Trace";
304            eval "require $obj_class";
305            die $@ if $@;
306            next;
307        }
308
309        if ($param =~ /^(PI|e|bexp|bpi|hex|oct)\z/) {
310            push @a, $param;
311            next;
312        }
313
314        croak("Unknown option '$param'");
315    }
316
317    eval "require $obj_class";
318    die $@ if $@;
319    $obj_class -> import(@import);
320
321    if ($ver) {
322        printf "%-31s v%s\n", $class, $class -> VERSION();
323        printf " lib => %-23s v%s\n",
324          $obj_class -> config("lib"), $obj_class -> config("lib_version");
325        printf "%-31s v%s\n", $obj_class, $obj_class -> VERSION();
326        exit;
327    }
328
329    $class -> export_to_level(1, $class, @a);   # export inf, NaN, etc.
330
331    overload::constant
332
333        # This takes care each number written as decimal integer and within the
334        # range of what perl can represent as an integer, e.g., "314", but not
335        # "3141592653589793238462643383279502884197169399375105820974944592307".
336
337        integer => sub {
338            #printf "Value '%s' handled by the 'integer' sub.\n", $_[0];
339            my $str = shift;
340            return $obj_class -> new($str);
341        },
342
343        # This takes care of each number written with a decimal point and/or
344        # using floating point notation, e.g., "3.", "3.0", "3.14e+2" (decimal),
345        # "0b1.101p+2" (binary), "03.14p+2" and "0o3.14p+2" (octal), and
346        # "0x3.14p+2" (hexadecimal).
347
348        float => sub {
349            #printf "# Value '%s' handled by the 'float' sub.\n", $_[0];
350            _float_constant(shift);
351        },
352
353        # Take care of each number written as an integer (no decimal point or
354        # exponent) using binary, octal, or hexadecimal notation, e.g., "0b101"
355        # (binary), "0314" and "0o314" (octal), and "0x314" (hexadecimal).
356
357        binary => sub {
358            #printf "# Value '%s' handled by the 'binary' sub.\n", $_[0];
359            my $str = shift;
360            return $obj_class -> new($str) if $str =~ /^0[XxBb]/;
361            $obj_class -> from_oct($str);
362        };
363}
364
365sub inf () { $obj_class -> binf(); }
366sub NaN () { $obj_class -> bnan(); }
367
368# This should depend on the current accuracy/precision. Fixme!
369sub PI  () { $obj_class -> new('3.141592653589793238462643383279502884197'); }
370sub e   () { $obj_class -> new('2.718281828459045235360287471352662497757'); }
371
372sub bpi ($) {
373    my $up = Math::BigFloat -> upgrade();   # get current upgrading, if any ...
374    Math::BigFloat -> upgrade(undef);       # ... and disable
375    my $x = Math::BigFloat -> bpi(@_);
376    Math::BigFloat -> upgrade($up);         # reset the upgrading
377    return $obj_class -> new($x);
378}
379
380sub bexp ($$) {
381    my $up = Math::BigFloat -> upgrade();   # get current upgrading, if any ...
382    Math::BigFloat -> upgrade(undef);       # ... and disable
383    my $x = Math::BigFloat -> new(shift);
384    $x -> bexp(@_);
385    Math::BigFloat -> upgrade($up);         # reset the upgrading
386    return $obj_class -> new($x);
387}
388
3891;
390
391__END__
392
393=pod
394
395=head1 NAME
396
397bigrat - transparent big rational number support for Perl
398
399=head1 SYNOPSIS
400
401    use bigrat;
402
403    print 2 + 4.5;                      # Math::BigRat 13/2
404    print 1/3 + 1/4;                    # Math::BigRat 7/12
405    print inf + 42;                     # Math::BigRat inf
406    print NaN * 7;                      # Math::BigRat NaN
407    print hex("0x1234567890123490");    # Perl v5.10.0 or later
408
409    {
410        no bigrat;
411        print 1/3;                      # 0.33333...
412    }
413
414    # for older Perls, import into current package:
415    use bigrat qw/hex oct/;
416    print hex("0x1234567890123490");
417    print oct("01234567890123490");
418
419=head1 DESCRIPTION
420
421All numeric literal in the given scope are converted to Math::BigRat objects.
422
423All operators (including basic math operations) except the range operator C<..>
424are overloaded.
425
426So, the following:
427
428    use bigrat;
429    $x = 1234;
430
431creates a Math::BigRat and stores a reference to in $x. This happens
432transparently and behind your back, so to speak.
433
434You can see this with the following:
435
436    perl -Mbigrat -le 'print ref(1234)'
437
438Since numbers are actually objects, you can call all the usual methods from
439Math::BigRat on them. This even works to some extent on expressions:
440
441    perl -Mbigrat -le '$x = 1234; print $x->bdec()'
442    perl -Mbigrat -le 'print 1234->copy()->binc();'
443    perl -Mbigrat -le 'print 1234->copy()->binc->badd(6);'
444    perl -Mbigrat -le 'print +(1234)->copy()->binc()'
445
446(Note that print doesn't do what you expect if the expression starts with
447'(' hence the C<+>)
448
449You can even chain the operations together as usual:
450
451    perl -Mbigrat -le 'print 1234->copy()->binc->badd(6);'
452    1241
453
454Please note the following does not work as expected (prints nothing), since
455overloading of '..' is not yet possible in Perl (as of v5.8.0):
456
457    perl -Mbigrat -le 'for (1..2) { print ref($_); }'
458
459=head2 Options
460
461C<bigrat> recognizes some options that can be passed while loading it via
462C<use>. The following options exist:
463
464=over 4
465
466=item a or accuracy
467
468This sets the accuracy for all math operations. The argument must be greater
469than or equal to zero. See Math::BigInt's bround() method for details.
470
471    perl -Mbigrat=a,50 -le 'print sqrt(20)'
472
473Note that setting precision and accuracy at the same time is not possible.
474
475=item p or precision
476
477This sets the precision for all math operations. The argument can be any
478integer. Negative values mean a fixed number of digits after the dot, while a
479positive value rounds to this digit left from the dot. 0 means round to integer.
480See Math::BigInt's bfround() method for details.
481
482    perl -Mbigrat=p,-50 -le 'print sqrt(20)'
483
484Note that setting precision and accuracy at the same time is not possible.
485
486=item t or trace
487
488This enables a trace mode and is primarily for debugging.
489
490=item l, lib, try, or only
491
492Load a different math lib, see L<Math Library>.
493
494    perl -Mbigrat=l,GMP -e 'print 2 ** 512'
495    perl -Mbigrat=lib,GMP -e 'print 2 ** 512'
496    perl -Mbigrat=try,GMP -e 'print 2 ** 512'
497    perl -Mbigrat=only,GMP -e 'print 2 ** 512'
498
499=item hex
500
501Override the built-in hex() method with a version that can handle big numbers.
502This overrides it by exporting it to the current package. Under Perl v5.10.0 and
503higher, this is not so necessary, as hex() is lexically overridden in the
504current scope whenever the C<bigrat> pragma is active.
505
506=item oct
507
508Override the built-in oct() method with a version that can handle big numbers.
509This overrides it by exporting it to the current package. Under Perl v5.10.0 and
510higher, this is not so necessary, as oct() is lexically overridden in the
511current scope whenever the C<bigrat> pragma is active.
512
513=item v or version
514
515this prints out the name and version of the modules and then exits.
516
517    perl -Mbigrat=v
518
519=back
520
521=head2 Math Library
522
523Math with the numbers is done (by default) by a backend library module called
524Math::BigInt::Calc. The default is equivalent to saying:
525
526    use bigrat lib => 'Calc';
527
528you can change this by using:
529
530    use bigrat lib => 'GMP';
531
532The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar,
533and if this also fails, revert to Math::BigInt::Calc:
534
535    use bigrat lib => 'Foo,Math::BigInt::Bar';
536
537Using c<lib> warns if none of the specified libraries can be found and
538L<Math::BigInt> fell back to one of the default libraries. To suppress this
539warning, use c<try> instead:
540
541    use bigrat try => 'GMP';
542
543If you want the code to die instead of falling back, use C<only> instead:
544
545    use bigrat only => 'GMP';
546
547Please see the respective module documentation for further details.
548
549=head2 Method calls
550
551Since all numbers are now objects, you can use all methods that are part of the
552Math::BigRat API.
553
554But a warning is in order. When using the following to make a copy of a number,
555only a shallow copy will be made.
556
557    $x = 9; $y = $x;
558    $x = $y = 7;
559
560Using the copy or the original with overloaded math is okay, e.g., the following
561work:
562
563    $x = 9; $y = $x;
564    print $x + 1, " ", $y,"\n";     # prints 10 9
565
566but calling any method that modifies the number directly will result in B<both>
567the original and the copy being destroyed:
568
569    $x = 9; $y = $x;
570    print $x->badd(1), " ", $y,"\n";        # prints 10 10
571
572    $x = 9; $y = $x;
573    print $x->binc(1), " ", $y,"\n";        # prints 10 10
574
575    $x = 9; $y = $x;
576    print $x->bmul(2), " ", $y,"\n";        # prints 18 18
577
578Using methods that do not modify, but test that the contents works:
579
580    $x = 9; $y = $x;
581    $z = 9 if $x->is_zero();                # works fine
582
583See the documentation about the copy constructor and C<=> in overload, as well
584as the documentation in Math::BigFloat for further details.
585
586=head2 Methods
587
588=over 4
589
590=item inf()
591
592A shortcut to return Math::BigRat->binf(). Useful because Perl does not always
593handle bareword C<inf> properly.
594
595=item NaN()
596
597A shortcut to return Math::BigRat->bnan(). Useful because Perl does not always
598handle bareword C<NaN> properly.
599
600=item e
601
602    # perl -Mbigrat=e -wle 'print e'
603
604Returns Euler's number C<e>, aka exp(1).
605
606=item PI
607
608    # perl -Mbigrat=PI -wle 'print PI'
609
610Returns PI.
611
612=item bexp()
613
614    bexp($power, $accuracy);
615
616Returns Euler's number C<e> raised to the appropriate power, to the wanted
617accuracy.
618
619Example:
620
621    # perl -Mbigrat=bexp -wle 'print bexp(1,80)'
622
623=item bpi()
624
625    bpi($accuracy);
626
627Returns PI to the wanted accuracy.
628
629Example:
630
631    # perl -Mbigrat=bpi -wle 'print bpi(80)'
632
633=item accuracy()
634
635Set or get the accuracy.
636
637=item precision()
638
639Set or get the precision.
640
641=item round_mode()
642
643Set or get the rounding mode.
644
645=item div_scale()
646
647Set or get the division scale.
648
649=item in_effect()
650
651    use bigrat;
652
653    print "in effect\n" if bigrat::in_effect;       # true
654    {
655        no bigrat;
656        print "in effect\n" if bigrat::in_effect;   # false
657    }
658
659Returns true or false if C<bigrat> is in effect in the current scope.
660
661This method only works on Perl v5.9.4 or later.
662
663=back
664
665=head1 CAVEATS
666
667=over 4
668
669=item Hexadecimal, octal, and binary floating point literals
670
671Perl (and this module) accepts hexadecimal, octal, and binary floating point
672literals, but use them with care with Perl versions before v5.32.0, because some
673versions of Perl silently give the wrong result.
674
675=item Operator vs literal overloading
676
677C<bigrat> works by overloading handling of integer and floating point literals,
678converting them to L<Math::BigRat> objects.
679
680This means that arithmetic involving only string values or string literals are
681performed using Perl's built-in operators.
682
683For example:
684
685    use bigrat;
686    my $x = "900000000000000009";
687    my $y = "900000000000000007";
688    print $x - $y;
689
690outputs C<0> on default 32-bit builds, since C<bigrat> never sees the string
691literals. To ensure the expression is all treated as C<Math::BigRat> objects,
692use a literal number in the expression:
693
694    print +(0+$x) - $y;
695
696=item Ranges
697
698Perl does not allow overloading of ranges, so you can neither safely use ranges
699with C<bigrat> endpoints, nor is the iterator variable a C<Math::BigRat>.
700
701    use 5.010;
702    for my $i (12..13) {
703      for my $j (20..21) {
704        say $i ** $j;  # produces a floating-point number,
705                       # not an object
706      }
707    }
708
709=item in_effect()
710
711This method only works on Perl v5.9.4 or later.
712
713=item hex()/oct()
714
715C<bigrat> overrides these routines with versions that can also handle big
716integer values. Under Perl prior to version v5.9.4, however, this will not
717happen unless you specifically ask for it with the two import tags "hex" and
718"oct" - and then it will be global and cannot be disabled inside a scope with
719C<no bigrat>:
720
721    use bigrat qw/hex oct/;
722
723    print hex("0x1234567890123456");
724    {
725        no bigrat;
726        print hex("0x1234567890123456");
727    }
728
729The second call to hex() will warn about a non-portable constant.
730
731Compare this to:
732
733    use bigrat;
734
735    # will warn only under Perl older than v5.9.4
736    print hex("0x1234567890123456");
737
738=back
739
740=head1 EXAMPLES
741
742    perl -Mbigrat -le 'print sqrt(33)'
743    perl -Mbigrat -le 'print 2**255'
744    perl -Mbigrat -le 'print 4.5+2**255'
745    perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3'
746    perl -Mbigrat -le 'print 12->is_odd()';
747    perl -Mbigrat=l,GMP -le 'print 7 ** 7777'
748
749=head1 BUGS
750
751Please report any bugs or feature requests to
752C<bug-bignum at rt.cpan.org>, or through the web interface at
753L<https://rt.cpan.org/Ticket/Create.html?Queue=bignum> (requires login).
754We will be notified, and then you'll automatically be notified of
755progress on your bug as I make changes.
756
757=head1 SUPPORT
758
759You can find documentation for this module with the perldoc command.
760
761    perldoc bigrat
762
763You can also look for information at:
764
765=over 4
766
767=item * GitHub
768
769L<https://github.com/pjacklam/p5-bignum>
770
771=item * RT: CPAN's request tracker
772
773L<https://rt.cpan.org/Dist/Display.html?Name=bignum>
774
775=item * MetaCPAN
776
777L<https://metacpan.org/release/bignum>
778
779=item * CPAN Testers Matrix
780
781L<http://matrix.cpantesters.org/?dist=bignum>
782
783=item * CPAN Ratings
784
785L<https://cpanratings.perl.org/dist/bignum>
786
787=back
788
789=head1 LICENSE
790
791This program is free software; you may redistribute it and/or modify it under
792the same terms as Perl itself.
793
794=head1 SEE ALSO
795
796L<bignum> and L<bigint>.
797
798L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigRat> and L<Math::Big> as well as
799L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
800
801=head1 AUTHORS
802
803=over 4
804
805=item *
806
807(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
808
809=item *
810
811Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-.
812
813=back
814
815=cut
816