Remove unused Module::Build tests
[p5sagit/p5-mst-13.2.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 );
b4bc5691 7@EXPORT_OK = qw( );
8@EXPORT = qw( inf NaN );
126f3c5f 9
10use strict;
95a2d02c 11use overload;
d1a15766 12require bigint; # no "use" to avoid callind import
126f3c5f 13
14##############################################################################
15
d1a15766 16BEGIN
17 {
18 *inf = \&bigint::inf;
19 *NaN = \&bigint::NaN;
20 }
21
126f3c5f 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 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 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 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 90sub import
91 {
92 my $self = shift;
93
94 # see also bignum->import() for additional comments
95
4440d13a 96 $^H{bigrat} = 1; # we are in effect
97
d1a15766 98 # for newer Perls always override hex() and oct() with a lexical version:
99 if ($] > 5.009004)
100 {
101 no warnings 'redefine';
102 *CORE::GLOBAL::oct = \&_oct;
103 *CORE::GLOBAL::hex = \&_hex;
104 }
126f3c5f 105 # some defaults
bd49aa09 106 my $lib = ''; my $lib_kind = 'try'; my $upgrade = 'Math::BigFloat';
126f3c5f 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 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 125 $lib = $_[$i+1] || '';
126 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
b68b7ab1 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 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 151 elsif ($_[$i] eq 'hex')
152 {
153 splice @a, $j, 1; $j --;
154 no warnings 'redefine';
155 *CORE::GLOBAL::hex = \&bigint::_hex_global;
156 }
157 elsif ($_[$i] eq 'oct')
158 {
159 splice @a, $j, 1; $j --;
160 no warnings 'redefine';
161 *CORE::GLOBAL::oct = \&bigint::_oct_global;
162 }
126f3c5f 163 else
164 {
165 die ("unknown option $_[$i]");
166 }
167 }
168 my $class;
169 $_lite = 0; # using M::BI::L ?
170 if ($trace)
171 {
172 require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
173 $upgrade = 'Math::BigFloat::Trace';
126f3c5f 174 }
175 else
176 {
177 # see if we can find Math::BigInt::Lite
178 if (!defined $a && !defined $p) # rounding won't work to well
179 {
180 eval 'require Math::BigInt::Lite;';
181 if ($@ eq '')
182 {
183 @import = ( ); # :constant in Lite, not MBI
184 Math::BigInt::Lite->import( ':constant' );
185 $_lite= 1; # signal okay
186 }
187 }
188 require Math::BigInt if $_lite == 0; # not already loaded?
189 $class = 'Math::BigInt'; # regardless of MBIL or not
190 }
bd49aa09 191 push @import, $lib_kind => $lib if $lib ne '';
126f3c5f 192 # Math::BigInt::Trace or plain Math::BigInt
233f7bc0 193 $class->import(@import, upgrade => $upgrade);
126f3c5f 194
195 require Math::BigFloat;
196 Math::BigFloat->import( upgrade => 'Math::BigRat', ':constant' );
197 require Math::BigRat;
b68b7ab1 198
199 bigrat->accuracy($a) if defined $a;
200 bigrat->precision($p) if defined $p;
126f3c5f 201 if ($ver)
202 {
203 print "bigrat\t\t\t v$VERSION\n";
204 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
205 print "Math::BigInt\t\t v$Math::BigInt::VERSION";
206 my $config = Math::BigInt->config();
207 print " lib => $config->{lib} v$config->{lib_version}\n";
208 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
209 print "Math::BigRat\t\t v$Math::BigRat::VERSION\n";
210 exit;
211 }
95a2d02c 212
213 # Take care of octal/hexadecimal constants
d1a15766 214 overload::constant binary => sub { bigint::_binary_constant(shift) };
95a2d02c 215
4440d13a 216 # if another big* was already loaded:
217 my ($package) = caller();
218
219 no strict 'refs';
220 if (!defined *{"${package}::inf"})
221 {
222 $self->export_to_level(1,$self,@a); # export inf and NaN
223 }
126f3c5f 224 }
225
2261;
227
228__END__
229
230=head1 NAME
231
b1f79218 232bigrat - Transparent BigNumber/BigRational support for Perl
126f3c5f 233
234=head1 SYNOPSIS
235
236 use bigrat;
237
4440d13a 238 print 2 + 4.5,"\n"; # BigFloat 6.5
126f3c5f 239 print 1/3 + 1/4,"\n"; # produces 7/12
240
4440d13a 241 {
242 no bigrat;
243 print 1/3,"\n"; # 0.33333...
244 }
245
d1a15766 246 # Note that this will make hex() and oct() be globally overriden:
247 use bigrat qw/hex oct/;
248 print hex("0x1234567890123490"),"\n";
249 print oct("01234567890123490"),"\n";
250
126f3c5f 251=head1 DESCRIPTION
252
3c4b39be 253All operators (including basic math operations) are overloaded. Integer and
126f3c5f 254floating-point constants are created as proper BigInts or BigFloats,
255respectively.
256
257Other than L<bignum>, this module upgrades to Math::BigRat, meaning that
258instead of 2.5 you will get 2+1/2 as output.
259
b68b7ab1 260=head2 Modules Used
126f3c5f 261
262C<bigrat> is just a thin wrapper around various modules of the Math::BigInt
263family. Think of it as the head of the family, who runs the shop, and orders
264the others to do the work.
265
266The following modules are currently used by bignum:
267
268 Math::BigInt::Lite (for speed, and only if it is loadable)
269 Math::BigInt
270 Math::BigFloat
271 Math::BigRat
272
b68b7ab1 273=head2 Math Library
126f3c5f 274
275Math with the numbers is done (by default) by a module called
276Math::BigInt::Calc. This is equivalent to saying:
277
278 use bigrat lib => 'Calc';
279
280You can change this by using:
281
bd49aa09 282 use bignum lib => 'GMP';
126f3c5f 283
284The following would first try to find Math::BigInt::Foo, then
285Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
286
287 use bigrat lib => 'Foo,Math::BigInt::Bar';
288
bd49aa09 289Using C<lib> warns if none of the specified libraries can be found and
290L<Math::BigInt> did fall back to one of the default libraries.
291To supress this warning, use C<try> instead:
292
293 use bignum try => 'GMP';
294
295If you want the code to die instead of falling back, use C<only> instead:
296
297 use bignum only => 'GMP';
298
126f3c5f 299Please see respective module documentation for further details.
300
b68b7ab1 301=head2 Sign
126f3c5f 302
b68b7ab1 303The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
126f3c5f 304
305A sign of 'NaN' is used to represent the result when input arguments are not
306numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
307minus infinity. You will get '+inf' when dividing a positive number by 0, and
308'-inf' when dividing any negative number by 0.
309
b68b7ab1 310=head2 Methods
126f3c5f 311
312Since all numbers are not objects, you can use all functions that are part of
313the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
314the fxxx() notation, though. This makes you independed on the fact that the
315underlying object might morph into a different class than BigFloat.
316
95a2d02c 317=over 2
318
319=item inf()
320
321A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
322handle bareword C<inf> properly.
323
324=item NaN()
325
326A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
327handle bareword C<NaN> properly.
328
329=item upgrade()
330
331Return the class that numbers are upgraded to, is in fact returning
332C<$Math::BigInt::upgrade>.
333
4440d13a 334=item in_effect()
335
336 use bigrat;
337
338 print "in effect\n" if bigrat::in_effect; # true
339 {
340 no bigrat;
341 print "in effect\n" if bigrat::in_effect; # false
342 }
343
344Returns true or false if C<bigrat> is in effect in the current scope.
345
346This method only works on Perl v5.9.4 or later.
347
95a2d02c 348=back
349
350=head2 MATH LIBRARY
351
352Math with the numbers is done (by default) by a module called
353
354=head2 Cavaet
990fb837 355
356But a warning is in order. When using the following to make a copy of a number,
357only a shallow copy will be made.
358
359 $x = 9; $y = $x;
360 $x = $y = 7;
361
b68b7ab1 362If you want to make a real copy, use the following:
363
364 $y = $x->copy();
365
990fb837 366Using the copy or the original with overloaded math is okay, e.g. the
367following work:
368
369 $x = 9; $y = $x;
370 print $x + 1, " ", $y,"\n"; # prints 10 9
371
372but calling any method that modifies the number directly will result in
3c4b39be 373B<both> the original and the copy being destroyed:
990fb837 374
375 $x = 9; $y = $x;
376 print $x->badd(1), " ", $y,"\n"; # prints 10 10
377
378 $x = 9; $y = $x;
379 print $x->binc(1), " ", $y,"\n"; # prints 10 10
380
381 $x = 9; $y = $x;
382 print $x->bmul(2), " ", $y,"\n"; # prints 18 18
383
384Using methods that do not modify, but testthe contents works:
385
386 $x = 9; $y = $x;
387 $z = 9 if $x->is_zero(); # works fine
388
389See the documentation about the copy constructor and C<=> in overload, as
390well as the documentation in BigInt for further details.
391
b68b7ab1 392=head2 Options
393
394bignum recognizes some options that can be passed while loading it via use.
395The options can (currently) be either a single letter form, or the long form.
396The following options exist:
397
398=over 2
399
400=item a or accuracy
401
402This sets the accuracy for all math operations. The argument must be greater
403than or equal to zero. See Math::BigInt's bround() function for details.
404
405 perl -Mbigrat=a,50 -le 'print sqrt(20)'
406
95a2d02c 407Note that setting precision and accurary at the same time is not possible.
408
b68b7ab1 409=item p or precision
410
411This sets the precision for all math operations. The argument can be any
412integer. Negative values mean a fixed number of digits after the dot, while
413a positive value rounds to this digit left from the dot. 0 or 1 mean round to
414integer. See Math::BigInt's bfround() function for details.
415
416 perl -Mbigrat=p,-50 -le 'print sqrt(20)'
417
95a2d02c 418Note that setting precision and accurary at the same time is not possible.
419
b68b7ab1 420=item t or trace
421
422This enables a trace mode and is primarily for debugging bignum or
423Math::BigInt/Math::BigFloat.
424
425=item l or lib
426
427Load a different math lib, see L<MATH LIBRARY>.
428
429 perl -Mbigrat=l,GMP -e 'print 2 ** 512'
430
431Currently there is no way to specify more than one library on the command
95a2d02c 432line. This means the following does not work:
433
434 perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
435
436This will be hopefully fixed soon ;)
b68b7ab1 437
d1a15766 438=item hex
439
440Override the build-in hex() method with a version that can handle big
441integers. Note that under Perl v5.9.4 or ealier, this will be global
442and cannot be disabled with "no bigint;".
443
444=item oct
445
446Override the build-in oct() method with a version that can handle big
447integers. Note that under Perl v5.9.4 or ealier, this will be global
448and cannot be disabled with "no bigint;".
449
b68b7ab1 450=item v or version
451
452This prints out the name and version of all modules used and then exits.
453
454 perl -Mbigrat=v
455
95a2d02c 456=back
457
d1a15766 458=head1 CAVAETS
459
460=over 2
461
462=item in_effect()
463
464This method only works on Perl v5.9.4 or later.
465
466=item hex()/oct()
467
468C<bigint> overrides these routines with versions that can also handle
469big integer values. Under Perl prior to version v5.9.4, however, this
470will not happen unless you specifically ask for it with the two
471import tags "hex" and "oct" - and then it will be global and cannot be
472disabled inside a scope with "no bigint":
473
474 use bigint qw/hex oct/;
475
476 print hex("0x1234567890123456");
477 {
478 no bigint;
479 print hex("0x1234567890123456");
480 }
481
482The second call to hex() will warn about a non-portable constant.
483
484Compare this to:
485
486 use bigint;
487
488 # will warn only under Perl older than v5.9.4
489 print hex("0x1234567890123456");
490
491=back
492
126f3c5f 493=head1 EXAMPLES
494
495 perl -Mbigrat -le 'print sqrt(33)'
496 perl -Mbigrat -le 'print 2*255'
497 perl -Mbigrat -le 'print 4.5+2*255'
498 perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3'
499 perl -Mbigrat -le 'print 12->is_odd()';
95a2d02c 500 perl -Mbignum=l,GMP -le 'print 7 ** 7777'
126f3c5f 501
502=head1 LICENSE
503
504This program is free software; you may redistribute it and/or modify it under
505the same terms as Perl itself.
506
507=head1 SEE ALSO
508
509Especially L<bignum>.
510
511L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
512as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
513
514=head1 AUTHORS
515
95a2d02c 516(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
126f3c5f 517
518=cut