This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Refactoring the /Can't return (?:array|hash) to scalar context/ croak
[perl5.git] / lib / bigrat.pm
CommitLineData
126f3c5f 1package bigrat;
95a2d02c 2use 5.006002;
126f3c5f 3
4440d13a 4$VERSION = '0.22';
b68b7ab1 5require Exporter;
d1a15766 6@ISA = qw( bigint );
d98d5fa0
T
7@EXPORT_OK = qw( PI e bpi bexp );
8@EXPORT = qw( inf NaN );
126f3c5f
JH
9
10use strict;
95a2d02c 11use overload;
d1a15766 12require bigint; # no "use" to avoid callind import
126f3c5f
JH
13
14##############################################################################
15
d1a15766
T
16BEGIN
17 {
18 *inf = \&bigint::inf;
19 *NaN = \&bigint::NaN;
20 }
21
126f3c5f
JH
22# These are all alike, and thus faked by AUTOLOAD
23
24my @faked = qw/round_mode accuracy precision div_scale/;
25use vars qw/$VERSION $AUTOLOAD $_lite/; # _lite for testsuite
26
27sub AUTOLOAD
28 {
29 my $name = $AUTOLOAD;
30
31 $name =~ s/.*:://; # split package
32 no strict 'refs';
33 foreach my $n (@faked)
34 {
35 if ($n eq $name)
36 {
37 *{"bigrat::$name"} = sub
38 {
39 my $self = shift;
40 no strict 'refs';
41 if (defined $_[0])
42 {
43 Math::BigInt->$name($_[0]);
44 Math::BigFloat->$name($_[0]);
990fb837 45 return Math::BigRat->$name($_[0]);
126f3c5f
JH
46 }
47 return Math::BigInt->$name();
48 };
49 return &$name;
50 }
51 }
52
53 # delayed load of Carp and avoid recursion
54 require Carp;
55 Carp::croak ("Can't call bigrat\-\>$name, not a valid method");
56 }
57
4440d13a
T
58sub unimport
59 {
60 $^H{bigrat} = undef; # no longer in effect
61 overload::remove_constant('binary','','float','','integer');
62 }
63
64sub in_effect
65 {
66 my $level = shift || 0;
67 my $hinthash = (caller($level))[10];
68 $hinthash->{bigrat};
69 }
70
d1a15766
T
71#############################################################################
72# the following two routines are for Perl 5.9.4 or later and are lexical
73
74sub _hex
75 {
76 return CORE::hex($_[0]) unless in_effect(1);
77 my $i = $_[0];
78 $i = '0x'.$i unless $i =~ /^0x/;
79 Math::BigInt->new($i);
80 }
81
82sub _oct
83 {
84 return CORE::oct($_[0]) unless in_effect(1);
85 my $i = $_[0];
86 return Math::BigInt->from_oct($i) if $i =~ /^0[0-7]/;
87 Math::BigInt->new($i);
88 }
89
126f3c5f
JH
90sub import
91 {
92 my $self = shift;
93
94 # see also bignum->import() for additional comments
95
4440d13a
T
96 $^H{bigrat} = 1; # we are in effect
97
075d4edd 98 my ($hex,$oct);
d1a15766
T
99 # for newer Perls always override hex() and oct() with a lexical version:
100 if ($] > 5.009004)
101 {
075d4edd
RGS
102 $oct = \&_oct;
103 $hex = \&_hex;
d1a15766 104 }
126f3c5f 105 # some defaults
bd49aa09 106 my $lib = ''; my $lib_kind = 'try'; my $upgrade = 'Math::BigFloat';
126f3c5f
JH
107
108 my @import = ( ':constant' ); # drive it w/ constant
109 my @a = @_; my $l = scalar @_; my $j = 0;
110 my ($a,$p);
111 my ($ver,$trace); # version? trace?
112 for ( my $i = 0; $i < $l ; $i++,$j++ )
113 {
114 if ($_[$i] eq 'upgrade')
115 {
116 # this causes upgrading
117 $upgrade = $_[$i+1]; # or undef to disable
118 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
119 splice @a, $j, $s; $j -= $s;
120 }
bd49aa09 121 elsif ($_[$i] =~ /^(l|lib|try|only)$/)
126f3c5f
JH
122 {
123 # this causes a different low lib to take care...
bd49aa09 124 $lib_kind = $1; $lib_kind = 'lib' if $lib_kind eq 'l';
126f3c5f
JH
125 $lib = $_[$i+1] || '';
126 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
b68b7ab1
T
127 splice @a, $j, $s; $j -= $s; $i++;
128 }
129 elsif ($_[$i] =~ /^(a|accuracy)$/)
130 {
131 $a = $_[$i+1];
132 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
133 splice @a, $j, $s; $j -= $s; $i++;
134 }
135 elsif ($_[$i] =~ /^(p|precision)$/)
136 {
137 $p = $_[$i+1];
138 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
139 splice @a, $j, $s; $j -= $s; $i++;
126f3c5f
JH
140 }
141 elsif ($_[$i] =~ /^(v|version)$/)
142 {
143 $ver = 1;
144 splice @a, $j, 1; $j --;
145 }
146 elsif ($_[$i] =~ /^(t|trace)$/)
147 {
148 $trace = 1;
149 splice @a, $j, 1; $j --;
150 }
d1a15766
T
151 elsif ($_[$i] eq 'hex')
152 {
153 splice @a, $j, 1; $j --;
075d4edd 154 $hex = \&bigint::_hex_global;
d1a15766
T
155 }
156 elsif ($_[$i] eq 'oct')
157 {
158 splice @a, $j, 1; $j --;
075d4edd 159 $oct = \&bigint::_oct_global;
d1a15766 160 }
d98d5fa0 161 elsif ($_[$i] !~ /^(PI|e|bpi|bexp)\z/)
126f3c5f
JH
162 {
163 die ("unknown option $_[$i]");
164 }
165 }
166 my $class;
167 $_lite = 0; # using M::BI::L ?
168 if ($trace)
169 {
170 require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
171 $upgrade = 'Math::BigFloat::Trace';
126f3c5f
JH
172 }
173 else
174 {
175 # see if we can find Math::BigInt::Lite
176 if (!defined $a && !defined $p) # rounding won't work to well
177 {
178 eval 'require Math::BigInt::Lite;';
179 if ($@ eq '')
180 {
181 @import = ( ); # :constant in Lite, not MBI
182 Math::BigInt::Lite->import( ':constant' );
183 $_lite= 1; # signal okay
184 }
185 }
186 require Math::BigInt if $_lite == 0; # not already loaded?
187 $class = 'Math::BigInt'; # regardless of MBIL or not
188 }
bd49aa09 189 push @import, $lib_kind => $lib if $lib ne '';
126f3c5f 190 # Math::BigInt::Trace or plain Math::BigInt
233f7bc0 191 $class->import(@import, upgrade => $upgrade);
126f3c5f
JH
192
193 require Math::BigFloat;
194 Math::BigFloat->import( upgrade => 'Math::BigRat', ':constant' );
195 require Math::BigRat;
b68b7ab1
T
196
197 bigrat->accuracy($a) if defined $a;
198 bigrat->precision($p) if defined $p;
126f3c5f
JH
199 if ($ver)
200 {
201 print "bigrat\t\t\t v$VERSION\n";
202 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
203 print "Math::BigInt\t\t v$Math::BigInt::VERSION";
204 my $config = Math::BigInt->config();
205 print " lib => $config->{lib} v$config->{lib_version}\n";
206 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
207 print "Math::BigRat\t\t v$Math::BigRat::VERSION\n";
208 exit;
209 }
95a2d02c
T
210
211 # Take care of octal/hexadecimal constants
d1a15766 212 overload::constant binary => sub { bigint::_binary_constant(shift) };
95a2d02c 213
4440d13a
T
214 # if another big* was already loaded:
215 my ($package) = caller();
216
217 no strict 'refs';
218 if (!defined *{"${package}::inf"})
219 {
220 $self->export_to_level(1,$self,@a); # export inf and NaN
221 }
075d4edd
RGS
222 {
223 no warnings 'redefine';
224 *CORE::GLOBAL::oct = $oct if $oct;
225 *CORE::GLOBAL::hex = $hex if $hex;
226 }
126f3c5f
JH
227 }
228
d98d5fa0
T
229sub PI () { Math::BigFloat->new('3.141592653589793238462643383279502884197'); }
230sub e () { Math::BigFloat->new('2.718281828459045235360287471352662497757'); }
231
232sub bpi ($) { local $Math::BigFloat::upgrade; Math::BigFloat::bpi(@_); }
233
234sub bexp ($$)
235 {
236 local $Math::BigFloat::upgrade;
237 my $x = Math::BigFloat->new($_[0]); $x->bexp($_[1]);
238 }
fade31f0 239
126f3c5f
JH
2401;
241
242__END__
243
244=head1 NAME
245
b1f79218 246bigrat - Transparent BigNumber/BigRational support for Perl
126f3c5f
JH
247
248=head1 SYNOPSIS
249
250 use bigrat;
251
4440d13a 252 print 2 + 4.5,"\n"; # BigFloat 6.5
126f3c5f
JH
253 print 1/3 + 1/4,"\n"; # produces 7/12
254
4440d13a
T
255 {
256 no bigrat;
257 print 1/3,"\n"; # 0.33333...
258 }
259
d1a15766
T
260 # Note that this will make hex() and oct() be globally overriden:
261 use bigrat qw/hex oct/;
262 print hex("0x1234567890123490"),"\n";
263 print oct("01234567890123490"),"\n";
264
126f3c5f
JH
265=head1 DESCRIPTION
266
3c4b39be 267All operators (including basic math operations) are overloaded. Integer and
126f3c5f
JH
268floating-point constants are created as proper BigInts or BigFloats,
269respectively.
270
271Other than L<bignum>, this module upgrades to Math::BigRat, meaning that
272instead of 2.5 you will get 2+1/2 as output.
273
b68b7ab1 274=head2 Modules Used
126f3c5f
JH
275
276C<bigrat> is just a thin wrapper around various modules of the Math::BigInt
277family. Think of it as the head of the family, who runs the shop, and orders
278the others to do the work.
279
280The following modules are currently used by bignum:
281
282 Math::BigInt::Lite (for speed, and only if it is loadable)
283 Math::BigInt
284 Math::BigFloat
285 Math::BigRat
286
b68b7ab1 287=head2 Math Library
126f3c5f
JH
288
289Math with the numbers is done (by default) by a module called
290Math::BigInt::Calc. This is equivalent to saying:
291
292 use bigrat lib => 'Calc';
293
294You can change this by using:
295
bd49aa09 296 use bignum lib => 'GMP';
126f3c5f
JH
297
298The following would first try to find Math::BigInt::Foo, then
299Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
300
301 use bigrat lib => 'Foo,Math::BigInt::Bar';
302
bd49aa09
SP
303Using C<lib> warns if none of the specified libraries can be found and
304L<Math::BigInt> did fall back to one of the default libraries.
305To supress this warning, use C<try> instead:
306
307 use bignum try => 'GMP';
308
309If you want the code to die instead of falling back, use C<only> instead:
310
311 use bignum only => 'GMP';
312
126f3c5f
JH
313Please see respective module documentation for further details.
314
b68b7ab1 315=head2 Sign
126f3c5f 316
b68b7ab1 317The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
126f3c5f
JH
318
319A sign of 'NaN' is used to represent the result when input arguments are not
320numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
321minus infinity. You will get '+inf' when dividing a positive number by 0, and
322'-inf' when dividing any negative number by 0.
323
b68b7ab1 324=head2 Methods
126f3c5f
JH
325
326Since all numbers are not objects, you can use all functions that are part of
327the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
328the fxxx() notation, though. This makes you independed on the fact that the
329underlying object might morph into a different class than BigFloat.
330
95a2d02c
T
331=over 2
332
333=item inf()
334
335A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
336handle bareword C<inf> properly.
337
338=item NaN()
339
340A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
341handle bareword C<NaN> properly.
342
d98d5fa0
T
343=item e
344
345 # perl -Mbigrat=e -wle 'print e'
346
347Returns Euler's number C<e>, aka exp(1).
348
349=item PI
350
351 # perl -Mbigrat=PI -wle 'print PI'
352
353Returns PI.
354
355=item bexp()
356
357 bexp($power,$accuracy);
358
359
360Returns Euler's number C<e> raised to the appropriate power, to
361the wanted accuracy.
362
363Example:
364
365 # perl -Mbigrat=bexp -wle 'print bexp(1,80)'
366
367=item bpi()
368
369 bpi($accuracy);
fade31f0 370
d98d5fa0 371Returns PI to the wanted accuracy.
fade31f0 372
d98d5fa0 373Example:
fade31f0 374
d98d5fa0 375 # perl -Mbigrat=bpi -wle 'print bpi(80)'
fade31f0 376
95a2d02c
T
377=item upgrade()
378
379Return the class that numbers are upgraded to, is in fact returning
380C<$Math::BigInt::upgrade>.
381
4440d13a
T
382=item in_effect()
383
384 use bigrat;
385
386 print "in effect\n" if bigrat::in_effect; # true
387 {
388 no bigrat;
389 print "in effect\n" if bigrat::in_effect; # false
390 }
391
392Returns true or false if C<bigrat> is in effect in the current scope.
393
394This method only works on Perl v5.9.4 or later.
395
95a2d02c
T
396=back
397
398=head2 MATH LIBRARY
399
400Math with the numbers is done (by default) by a module called
401
402=head2 Cavaet
990fb837
RGS
403
404But a warning is in order. When using the following to make a copy of a number,
405only a shallow copy will be made.
406
407 $x = 9; $y = $x;
408 $x = $y = 7;
409
b68b7ab1
T
410If you want to make a real copy, use the following:
411
412 $y = $x->copy();
413
990fb837
RGS
414Using the copy or the original with overloaded math is okay, e.g. the
415following work:
416
417 $x = 9; $y = $x;
418 print $x + 1, " ", $y,"\n"; # prints 10 9
419
420but calling any method that modifies the number directly will result in
3c4b39be 421B<both> the original and the copy being destroyed:
990fb837
RGS
422
423 $x = 9; $y = $x;
424 print $x->badd(1), " ", $y,"\n"; # prints 10 10
425
426 $x = 9; $y = $x;
427 print $x->binc(1), " ", $y,"\n"; # prints 10 10
428
429 $x = 9; $y = $x;
430 print $x->bmul(2), " ", $y,"\n"; # prints 18 18
431
432Using methods that do not modify, but testthe contents works:
433
434 $x = 9; $y = $x;
435 $z = 9 if $x->is_zero(); # works fine
436
437See the documentation about the copy constructor and C<=> in overload, as
438well as the documentation in BigInt for further details.
439
b68b7ab1
T
440=head2 Options
441
442bignum recognizes some options that can be passed while loading it via use.
443The options can (currently) be either a single letter form, or the long form.
444The following options exist:
445
446=over 2
447
448=item a or accuracy
449
450This sets the accuracy for all math operations. The argument must be greater
451than or equal to zero. See Math::BigInt's bround() function for details.
452
453 perl -Mbigrat=a,50 -le 'print sqrt(20)'
454
95a2d02c
T
455Note that setting precision and accurary at the same time is not possible.
456
b68b7ab1
T
457=item p or precision
458
459This sets the precision for all math operations. The argument can be any
460integer. Negative values mean a fixed number of digits after the dot, while
461a positive value rounds to this digit left from the dot. 0 or 1 mean round to
462integer. See Math::BigInt's bfround() function for details.
463
464 perl -Mbigrat=p,-50 -le 'print sqrt(20)'
465
95a2d02c
T
466Note that setting precision and accurary at the same time is not possible.
467
b68b7ab1
T
468=item t or trace
469
470This enables a trace mode and is primarily for debugging bignum or
471Math::BigInt/Math::BigFloat.
472
473=item l or lib
474
475Load a different math lib, see L<MATH LIBRARY>.
476
477 perl -Mbigrat=l,GMP -e 'print 2 ** 512'
478
479Currently there is no way to specify more than one library on the command
95a2d02c
T
480line. This means the following does not work:
481
482 perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
483
484This will be hopefully fixed soon ;)
b68b7ab1 485
d1a15766
T
486=item hex
487
43cde5e1 488Override the built-in hex() method with a version that can handle big
d1a15766
T
489integers. Note that under Perl v5.9.4 or ealier, this will be global
490and cannot be disabled with "no bigint;".
491
492=item oct
493
43cde5e1 494Override the built-in oct() method with a version that can handle big
d1a15766
T
495integers. Note that under Perl v5.9.4 or ealier, this will be global
496and cannot be disabled with "no bigint;".
497
b68b7ab1
T
498=item v or version
499
500This prints out the name and version of all modules used and then exits.
501
502 perl -Mbigrat=v
503
95a2d02c
T
504=back
505
d1a15766
T
506=head1 CAVAETS
507
508=over 2
509
510=item in_effect()
511
512This method only works on Perl v5.9.4 or later.
513
514=item hex()/oct()
515
516C<bigint> overrides these routines with versions that can also handle
517big integer values. Under Perl prior to version v5.9.4, however, this
518will not happen unless you specifically ask for it with the two
519import tags "hex" and "oct" - and then it will be global and cannot be
520disabled inside a scope with "no bigint":
521
522 use bigint qw/hex oct/;
523
524 print hex("0x1234567890123456");
525 {
526 no bigint;
527 print hex("0x1234567890123456");
528 }
529
530The second call to hex() will warn about a non-portable constant.
531
532Compare this to:
533
534 use bigint;
535
536 # will warn only under Perl older than v5.9.4
537 print hex("0x1234567890123456");
538
539=back
540
126f3c5f
JH
541=head1 EXAMPLES
542
543 perl -Mbigrat -le 'print sqrt(33)'
544 perl -Mbigrat -le 'print 2*255'
545 perl -Mbigrat -le 'print 4.5+2*255'
546 perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3'
547 perl -Mbigrat -le 'print 12->is_odd()';
95a2d02c 548 perl -Mbignum=l,GMP -le 'print 7 ** 7777'
126f3c5f
JH
549
550=head1 LICENSE
551
552This program is free software; you may redistribute it and/or modify it under
553the same terms as Perl itself.
554
555=head1 SEE ALSO
556
557Especially L<bignum>.
558
559L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
560as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
561
562=head1 AUTHORS
563
95a2d02c 564(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
126f3c5f
JH
565
566=cut