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