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