Upgrade to Math::BigInt 1.86
[p5sagit/p5-mst-13.2.git] / lib / bignum.pm
CommitLineData
126f3c5f 1package bignum;
95a2d02c 2use 5.006002;
126f3c5f 3
bce28014 4$VERSION = '0.20';
126f3c5f 5use Exporter;
b4bc5691 6@EXPORT_OK = qw( );
7@EXPORT = qw( inf NaN );
8@ISA = qw( Exporter );
126f3c5f 9
10use strict;
95a2d02c 11use overload;
126f3c5f 12
13##############################################################################
14
15# These are all alike, and thus faked by AUTOLOAD
16
17my @faked = qw/round_mode accuracy precision div_scale/;
18use vars qw/$VERSION $AUTOLOAD $_lite/; # _lite for testsuite
19
20sub AUTOLOAD
21 {
22 my $name = $AUTOLOAD;
23
24 $name =~ s/.*:://; # split package
25 no strict 'refs';
26 foreach my $n (@faked)
27 {
28 if ($n eq $name)
29 {
30 *{"bignum::$name"} = sub
31 {
32 my $self = shift;
33 no strict 'refs';
34 if (defined $_[0])
35 {
36 Math::BigInt->$name($_[0]);
990fb837 37 return Math::BigFloat->$name($_[0]);
126f3c5f 38 }
39 return Math::BigInt->$name();
40 };
41 return &$name;
42 }
43 }
44
45 # delayed load of Carp and avoid recursion
46 require Carp;
47 Carp::croak ("Can't call bignum\-\>$name, not a valid method");
48 }
49
50sub upgrade
51 {
52 my $self = shift;
53 no strict 'refs';
54# if (defined $_[0])
55# {
56# $Math::BigInt::upgrade = $_[0];
57# $Math::BigFloat::upgrade = $_[0];
58# }
95a2d02c 59 $Math::BigInt::upgrade;
60 }
61
62sub _binary_constant
63 {
64 # this takes a binary/hexadecimal/octal constant string and returns it
65 # as string suitable for new. Basically it converts octal to decimal, and
66 # passes every thing else unmodified back.
67 my $string = shift;
68
69 return Math::BigInt->new($string) if $string =~ /^0[bx]/;
70
71 # so it must be an octal constant
72 Math::BigInt->from_oct($string);
126f3c5f 73 }
74
75sub import
76 {
77 my $self = shift;
78
79 # some defaults
233f7bc0 80 my $lib = '';
126f3c5f 81 my $upgrade = 'Math::BigFloat';
82 my $downgrade = 'Math::BigInt';
83
84 my @import = ( ':constant' ); # drive it w/ constant
85 my @a = @_; my $l = scalar @_; my $j = 0;
86 my ($ver,$trace); # version? trace?
87 my ($a,$p); # accuracy, precision
88 for ( my $i = 0; $i < $l ; $i++,$j++ )
89 {
90 if ($_[$i] eq 'upgrade')
91 {
92 # this causes upgrading
93 $upgrade = $_[$i+1]; # or undef to disable
94 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
95 splice @a, $j, $s; $j -= $s; $i++;
96 }
97 elsif ($_[$i] eq 'downgrade')
98 {
99 # this causes downgrading
100 $downgrade = $_[$i+1]; # or undef to disable
101 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
102 splice @a, $j, $s; $j -= $s; $i++;
103 }
104 elsif ($_[$i] =~ /^(l|lib)$/)
105 {
106 # this causes a different low lib to take care...
107 $lib = $_[$i+1] || '';
108 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
109 splice @a, $j, $s; $j -= $s; $i++;
110 }
111 elsif ($_[$i] =~ /^(a|accuracy)$/)
112 {
113 $a = $_[$i+1];
114 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
115 splice @a, $j, $s; $j -= $s; $i++;
116 }
117 elsif ($_[$i] =~ /^(p|precision)$/)
118 {
119 $p = $_[$i+1];
120 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
121 splice @a, $j, $s; $j -= $s; $i++;
122 }
123 elsif ($_[$i] =~ /^(v|version)$/)
124 {
125 $ver = 1;
126 splice @a, $j, 1; $j --;
127 }
128 elsif ($_[$i] =~ /^(t|trace)$/)
129 {
130 $trace = 1;
131 splice @a, $j, 1; $j --;
132 }
133 else { die "unknown option $_[$i]"; }
134 }
135 my $class;
136 $_lite = 0; # using M::BI::L ?
137 if ($trace)
138 {
139 require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
140 $upgrade = 'Math::BigFloat::Trace';
126f3c5f 141 }
142 else
143 {
144 # see if we can find Math::BigInt::Lite
145 if (!defined $a && !defined $p) # rounding won't work to well
146 {
147 eval 'require Math::BigInt::Lite;';
148 if ($@ eq '')
149 {
150 @import = ( ); # :constant in Lite, not MBI
151 Math::BigInt::Lite->import( ':constant' );
152 $_lite= 1; # signal okay
153 }
154 }
155 require Math::BigInt if $_lite == 0; # not already loaded?
156 $class = 'Math::BigInt'; # regardless of MBIL or not
233f7bc0 157 }
95a2d02c 158 push @import, 'try' => $lib if $lib ne '';
126f3c5f 159 # Math::BigInt::Trace or plain Math::BigInt
233f7bc0 160 $class->import(@import, upgrade => $upgrade);
126f3c5f 161
162 if ($trace)
163 {
164 require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace';
165 $downgrade = 'Math::BigInt::Trace';
126f3c5f 166 }
167 else
168 {
169 require Math::BigFloat; $class = 'Math::BigFloat';
170 }
171 $class->import(':constant','downgrade',$downgrade);
172
173 bignum->accuracy($a) if defined $a;
174 bignum->precision($p) if defined $p;
175 if ($ver)
176 {
177 print "bignum\t\t\t v$VERSION\n";
178 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
179 print "Math::BigInt\t\t v$Math::BigInt::VERSION";
180 my $config = Math::BigInt->config();
181 print " lib => $config->{lib} v$config->{lib_version}\n";
182 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
183 exit;
184 }
95a2d02c 185
186 # Take care of octal/hexadecimal constants
187 overload::constant 'binary' => sub { _binary_constant(shift) };
188
b4bc5691 189 $self->export_to_level(1,$self,@a); # export inf and NaN
126f3c5f 190 }
191
b4bc5691 192sub inf () { Math::BigInt->binf(); }
193sub NaN () { Math::BigInt->bnan(); }
194
126f3c5f 1951;
196
197__END__
198
199=head1 NAME
200
201bignum - Transparent BigNumber support for Perl
202
203=head1 SYNOPSIS
204
205 use bignum;
206
207 $x = 2 + 4.5,"\n"; # BigFloat 6.5
b4bc5691 208 print 2 ** 512 * 0.1,"\n"; # really is what you think it is
209 print inf * inf,"\n"; # prints inf
210 print NaN * 3,"\n"; # prints NaN
126f3c5f 211
212=head1 DESCRIPTION
213
214All operators (including basic math operations) are overloaded. Integer and
215floating-point constants are created as proper BigInts or BigFloats,
216respectively.
217
24716a00 218If you do
219
220 use bignum;
221
222at the top of your script, Math::BigFloat and Math::BigInt will be loaded
223and any constant number will be converted to an object (Math::BigFloat for
224floats like 3.1415 and Math::BigInt for integers like 1234).
225
226So, the following line:
227
228 $x = 1234;
229
230creates actually a Math::BigInt and stores a reference to in $x.
231This happens transparently and behind your back, so to speak.
232
233You can see this with the following:
234
235 perl -Mbignum -le 'print ref(1234)'
236
237Don't worry if it says Math::BigInt::Lite, bignum and friends will use Lite
238if it is installed since it is faster for some operations. It will be
3c4b39be 239automatically upgraded to BigInt whenever necessary:
24716a00 240
241 perl -Mbignum -le 'print ref(2**255)'
242
243This also means it is a bad idea to check for some specific package, since
244the actual contents of $x might be something unexpected. Due to the
3c4b39be 245transparent way of bignum C<ref()> should not be necessary, anyway.
24716a00 246
247Since Math::BigInt and BigFloat also overload the normal math operations,
248the following line will still work:
249
250 perl -Mbignum -le 'print ref(1234+1234)'
251
252Since numbers are actually objects, you can call all the usual methods from
253BigInt/BigFloat on them. This even works to some extent on expressions:
254
255 perl -Mbignum -le '$x = 1234; print $x->bdec()'
256 perl -Mbignum -le 'print 1234->binc();'
257 perl -Mbignum -le 'print 1234->binc->badd(6);'
258 perl -Mbignum -le 'print +(1234)->binc()'
259
260(Note that print doesn't do what you expect if the expression starts with
261'(' hence the C<+>)
262
263You can even chain the operations together as usual:
264
265 perl -Mbignum -le 'print 1234->binc->badd(6);'
266 1241
267
268Under bignum (or bigint or bigrat), Perl will "upgrade" the numbers
269appropriately. This means that:
270
271 perl -Mbignum -le 'print 1234+4.5'
272 1238.5
273
274will work correctly. These mixed cases don't do always work when using
275Math::BigInt or Math::BigFloat alone, or at least not in the way normal Perl
276scalars work.
277
278If you do want to work with large integers like under C<use integer;>, try
279C<use bigint;>:
280
281 perl -Mbigint -le 'print 1234.5+4.5'
282 1238
283
284There is also C<use bigrat;> which gives you big rationals:
285
286 perl -Mbigrat -le 'print 1234+4.1'
287 12381/10
288
289The entire upgrading/downgrading is still experimental and might not work
290as you expect or may even have bugs.
291
292You might get errors like this:
293
294 Can't use an undefined value as an ARRAY reference at
295 /usr/local/lib/perl5/5.8.0/Math/BigInt/Calc.pm line 864
296
297This means somewhere a routine got a BigFloat/Lite but expected a BigInt (or
298vice versa) and the upgrade/downgrad path was missing. This is a bug, please
299report it so that we can fix it.
300
301You might consider using just Math::BigInt or Math::BigFloat, since they
302allow you finer control over what get's done in which module/space. For
303instance, simple loop counters will be Math::BigInts under C<use bignum;> and
304this is slower than keeping them as Perl scalars:
305
306 perl -Mbignum -le 'for ($i = 0; $i < 10; $i++) { print ref($i); }'
307
308Please note the following does not work as expected (prints nothing), since
309overloading of '..' is not yet possible in Perl (as of v5.8.0):
310
311 perl -Mbignum -le 'for (1..2) { print ref($_); }'
312
b68b7ab1 313=head2 Options
126f3c5f 314
315bignum recognizes some options that can be passed while loading it via use.
316The options can (currently) be either a single letter form, or the long form.
317The following options exist:
318
319=over 2
320
321=item a or accuracy
322
323This sets the accuracy for all math operations. The argument must be greater
324than or equal to zero. See Math::BigInt's bround() function for details.
325
326 perl -Mbignum=a,50 -le 'print sqrt(20)'
327
95a2d02c 328Note that setting precision and accurary at the same time is not possible.
329
126f3c5f 330=item p or precision
331
332This sets the precision for all math operations. The argument can be any
333integer. Negative values mean a fixed number of digits after the dot, while
334a positive value rounds to this digit left from the dot. 0 or 1 mean round to
335integer. See Math::BigInt's bfround() function for details.
336
337 perl -Mbignum=p,-50 -le 'print sqrt(20)'
338
95a2d02c 339Note that setting precision and accurary at the same time is not possible.
340
126f3c5f 341=item t or trace
342
343This enables a trace mode and is primarily for debugging bignum or
344Math::BigInt/Math::BigFloat.
345
346=item l or lib
347
348Load a different math lib, see L<MATH LIBRARY>.
349
350 perl -Mbignum=l,GMP -e 'print 2 ** 512'
351
352Currently there is no way to specify more than one library on the command
95a2d02c 353line. This means the following does not work:
354
355 perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
356
357This will be hopefully fixed soon ;)
126f3c5f 358
359=item v or version
360
361This prints out the name and version of all modules used and then exits.
362
b68b7ab1 363 perl -Mbignum=v
126f3c5f 364
95a2d02c 365=back
366
b68b7ab1 367=head2 Methods
b4bc5691 368
369Beside import() and AUTOLOAD() there are only a few other methods.
370
24716a00 371Since all numbers are now objects, you can use all functions that are part of
372the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
373the fxxx() notation, though. This makes it possible that the underlying object
374might morph into a different class than BigFloat.
375
b68b7ab1 376=head2 Caveat
990fb837 377
378But a warning is in order. When using the following to make a copy of a number,
379only a shallow copy will be made.
380
381 $x = 9; $y = $x;
382 $x = $y = 7;
383
b68b7ab1 384If you want to make a real copy, use the following:
385
386 $y = $x->copy();
387
990fb837 388Using the copy or the original with overloaded math is okay, e.g. the
389following work:
390
391 $x = 9; $y = $x;
392 print $x + 1, " ", $y,"\n"; # prints 10 9
393
394but calling any method that modifies the number directly will result in
3c4b39be 395B<both> the original and the copy being destroyed:
990fb837 396
397 $x = 9; $y = $x;
398 print $x->badd(1), " ", $y,"\n"; # prints 10 10
399
400 $x = 9; $y = $x;
401 print $x->binc(1), " ", $y,"\n"; # prints 10 10
402
403 $x = 9; $y = $x;
404 print $x->bmul(2), " ", $y,"\n"; # prints 18 18
405
406Using methods that do not modify, but testthe contents works:
407
408 $x = 9; $y = $x;
409 $z = 9 if $x->is_zero(); # works fine
410
411See the documentation about the copy constructor and C<=> in overload, as
412well as the documentation in BigInt for further details.
413
b4bc5691 414=over 2
415
416=item inf()
417
3c4b39be 418A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
b4bc5691 419handle bareword C<inf> properly.
420
421=item NaN()
422
3c4b39be 423A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
b4bc5691 424handle bareword C<NaN> properly.
425
426=item upgrade()
427
428Return the class that numbers are upgraded to, is in fact returning
429C<$Math::BigInt::upgrade>.
430
431=back
432
126f3c5f 433=head2 MATH LIBRARY
434
435Math with the numbers is done (by default) by a module called
436Math::BigInt::Calc. This is equivalent to saying:
437
438 use bignum lib => 'Calc';
439
440You can change this by using:
441
442 use bignum lib => 'BitVect';
443
444The following would first try to find Math::BigInt::Foo, then
445Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
446
447 use bignum lib => 'Foo,Math::BigInt::Bar';
448
449Please see respective module documentation for further details.
450
451=head2 INTERNAL FORMAT
452
453The numbers are stored as objects, and their internals might change at anytime,
454especially between math operations. The objects also might belong to different
455classes, like Math::BigInt, or Math::BigFLoat. Mixing them together, even
456with normal scalars is not extraordinary, but normal and expected.
457
458You should not depend on the internal format, all accesses must go through
459accessor methods. E.g. looking at $x->{sign} is not a bright idea since there
460is no guaranty that the object in question has such a hashkey, nor is a hash
461underneath at all.
462
463=head2 SIGN
464
465The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
466You can access it with the sign() method.
467
468A sign of 'NaN' is used to represent the result when input arguments are not
469numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
470minus infinity. You will get '+inf' when dividing a positive number by 0, and
471'-inf' when dividing any negative number by 0.
472
126f3c5f 473=head1 MODULES USED
474
475C<bignum> is just a thin wrapper around various modules of the Math::BigInt
476family. Think of it as the head of the family, who runs the shop, and orders
477the others to do the work.
478
479The following modules are currently used by bignum:
480
481 Math::BigInt::Lite (for speed, and only if it is loadable)
482 Math::BigInt
483 Math::BigFloat
484
485=head1 EXAMPLES
486
487Some cool command line examples to impress the Python crowd ;)
488
489 perl -Mbignum -le 'print sqrt(33)'
490 perl -Mbignum -le 'print 2*255'
491 perl -Mbignum -le 'print 4.5+2*255'
492 perl -Mbignum -le 'print 3/7 + 5/7 + 8/3'
493 perl -Mbignum -le 'print 123->is_odd()'
494 perl -Mbignum -le 'print log(2)'
bce28014 495 perl -Mbignum -le 'print exp(1)'
126f3c5f 496 perl -Mbignum -le 'print 2 ** 0.5'
497 perl -Mbignum=a,65 -le 'print 2 ** 0.2'
95a2d02c 498 perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777'
126f3c5f 499
500=head1 LICENSE
501
502This program is free software; you may redistribute it and/or modify it under
503the same terms as Perl itself.
504
505=head1 SEE ALSO
506
507Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'>.
508
509L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
510as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
511
512=head1 AUTHORS
513
95a2d02c 514(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
126f3c5f 515
516=cut