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