Upgrade to Module-Build-0.2808
[p5sagit/p5-mst-13.2.git] / lib / bigint.pm
1 package bigint;
2 use 5.006002;
3
4 $VERSION = '0.10';
5 use Exporter;
6 @ISA            = qw( Exporter );
7 @EXPORT_OK      = qw( ); 
8 @EXPORT         = qw( inf NaN ); 
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       *{"bigint::$name"} = sub 
31         {
32         my $self = shift;
33         no strict 'refs';
34         if (defined $_[0])
35           {
36           return Math::BigInt->$name($_[0]);
37           }
38         return Math::BigInt->$name();
39         };
40       return &$name;
41       }
42     }
43  
44   # delayed load of Carp and avoid recursion
45   require Carp;
46   Carp::croak ("Can't call bigint\-\>$name, not a valid method");
47   }
48
49 sub upgrade
50   {
51   my $self = shift;
52   no strict 'refs';
53 #  if (defined $_[0])
54 #    {
55 #    $Math::BigInt::upgrade = $_[0];
56 #    }
57   $Math::BigInt::upgrade;
58   }
59
60 sub _binary_constant
61   {
62   # this takes a binary/hexadecimal/octal constant string and returns it
63   # as string suitable for new. Basically it converts octal to decimal, and
64   # passes every thing else unmodified back.
65   my $string = shift;
66
67   return Math::BigInt->new($string) if $string =~ /^0[bx]/;
68
69   # so it must be an octal constant
70   Math::BigInt->from_oct($string);
71   }
72
73 sub _float_constant
74   {
75   # this takes a floating point constant string and returns it truncated to
76   # integer. For instance, '4.5' => '4', '1.234e2' => '123' etc
77   my $float = shift;
78
79   # some simple cases first
80   return $float if ($float =~ /^[+-]?[0-9]+$/);         # '+123','-1','0' etc
81   return $float 
82     if ($float =~ /^[+-]?[0-9]+\.?[eE]\+?[0-9]+$/);     # 123e2, 123.e+2
83   return '0' if ($float =~ /^[+-]?[0]*\.[0-9]+$/);      # .2, 0.2, -.1
84   if ($float =~ /^[+-]?[0-9]+\.[0-9]*$/)                # 1., 1.23, -1.2 etc
85     {
86     $float =~ s/\..*//;
87     return $float;
88     }
89   my ($mis,$miv,$mfv,$es,$ev) = Math::BigInt::_split($float);
90   return $float if !defined $mis;       # doesn't look like a number to me
91   my $ec = int($$ev);
92   my $sign = $$mis; $sign = '' if $sign eq '+';
93   if ($$es eq '-')
94     {
95     # ignore fraction part entirely
96     if ($ec >= length($$miv))                   # 123.23E-4
97       {
98       return '0';
99       }
100     return $sign . substr ($$miv,0,length($$miv)-$ec);  # 1234.45E-2 = 12
101     }
102   # xE+y
103   if ($ec >= length($$mfv))
104     {
105     $ec -= length($$mfv);                       
106     return $sign.$$miv.$$mfv if $ec == 0;       # 123.45E+2 => 12345
107     return $sign.$$miv.$$mfv.'E'.$ec;           # 123.45e+3 => 12345e1
108     }
109   $mfv = substr($$mfv,0,$ec);
110   $sign.$$miv.$mfv;                             # 123.45e+1 => 1234
111   }
112
113 sub import 
114   {
115   my $self = shift;
116
117   # some defaults
118   my $lib = ''; my $lib_kind = 'try';
119
120   my @import = ( ':constant' );                         # drive it w/ constant
121   my @a = @_; my $l = scalar @_; my $j = 0;
122   my ($ver,$trace);                                     # version? trace?
123   my ($a,$p);                                           # accuracy, precision
124   for ( my $i = 0; $i < $l ; $i++,$j++ )
125     {
126     if ($_[$i] =~ /^(l|lib|try|only)$/)
127       {
128       # this causes a different low lib to take care...
129       $lib_kind = $1; $lib_kind = 'lib' if $lib_kind eq 'l';
130       $lib = $_[$i+1] || '';
131       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
132       splice @a, $j, $s; $j -= $s; $i++;
133       }
134     elsif ($_[$i] =~ /^(a|accuracy)$/)
135       {
136       $a = $_[$i+1];
137       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
138       splice @a, $j, $s; $j -= $s; $i++;
139       }
140     elsif ($_[$i] =~ /^(p|precision)$/)
141       {
142       $p = $_[$i+1];
143       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
144       splice @a, $j, $s; $j -= $s; $i++;
145       }
146     elsif ($_[$i] =~ /^(v|version)$/)
147       {
148       $ver = 1;
149       splice @a, $j, 1; $j --;
150       }
151     elsif ($_[$i] =~ /^(t|trace)$/)
152       {
153       $trace = 1;
154       splice @a, $j, 1; $j --;
155       }
156     else { die "unknown option $_[$i]"; }
157     }
158   my $class;
159   $_lite = 0;                                   # using M::BI::L ?
160   if ($trace)
161     {
162     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
163     }
164   else
165     {
166     # see if we can find Math::BigInt::Lite
167     if (!defined $a && !defined $p)             # rounding won't work to well
168       {
169       eval 'require Math::BigInt::Lite;';
170       if ($@ eq '')
171         {
172         @import = ( );                          # :constant in Lite, not MBI
173         Math::BigInt::Lite->import( ':constant' );
174         $_lite= 1;                              # signal okay
175         }
176       }
177     require Math::BigInt if $_lite == 0;        # not already loaded?
178     $class = 'Math::BigInt';                    # regardless of MBIL or not
179     }
180   push @import, $lib_kind => $lib if $lib ne '';
181   # Math::BigInt::Trace or plain Math::BigInt
182   $class->import(@import);
183
184   bigint->accuracy($a) if defined $a;
185   bigint->precision($p) if defined $p;
186   if ($ver)
187     {
188     print "bigint\t\t\t v$VERSION\n";
189     print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
190     print "Math::BigInt\t\t v$Math::BigInt::VERSION";
191     my $config = Math::BigInt->config();
192     print " lib => $config->{lib} v$config->{lib_version}\n";
193     exit;
194     }
195   # we take care of floating point constants, since BigFloat isn't available
196   # and BigInt doesn't like them:
197   overload::constant float => sub { Math::BigInt->new( _float_constant(shift) ); };
198   # Take care of octal/hexadecimal constants
199   overload::constant binary => sub { _binary_constant(shift) };
200
201   $self->export_to_level(1,$self,@a);           # export inf and NaN
202   }
203
204 sub inf () { Math::BigInt->binf(); }
205 sub NaN () { Math::BigInt->bnan(); }
206
207 1;
208
209 __END__
210
211 =head1 NAME
212
213 bigint - Transparent BigInteger support for Perl
214
215 =head1 SYNOPSIS
216
217   use bigint;
218
219   $x = 2 + 4.5,"\n";                    # BigInt 6
220   print 2 ** 512,"\n";                  # really is what you think it is
221   print inf + 42,"\n";                  # inf
222   print NaN * 7,"\n";                   # NaN
223
224 =head1 DESCRIPTION
225
226 All operators (including basic math operations) are overloaded. Integer
227 constants are created as proper BigInts.
228
229 Floating point constants are truncated to integer. All results are also
230 truncated.
231
232 =head2 Options
233
234 bigint recognizes some options that can be passed while loading it via use.
235 The options can (currently) be either a single letter form, or the long form.
236 The following options exist:
237
238 =over 2
239
240 =item a or accuracy
241
242 This sets the accuracy for all math operations. The argument must be greater
243 than or equal to zero. See Math::BigInt's bround() function for details.
244
245         perl -Mbigint=a,2 -le 'print 12345+1'
246
247 Note that setting precision and accurary at the same time is not possible.
248
249 =item p or precision
250
251 This sets the precision for all math operations. The argument can be any
252 integer. Negative values mean a fixed number of digits after the dot, and
253 are <B>ignored</B> since all operations happen in integer space.
254 A positive value rounds to this digit left from the dot. 0 or 1 mean round to
255 integer and are ignore like negative values.
256
257 See Math::BigInt's bfround() function for details.
258
259         perl -Mbignum=p,5 -le 'print 123456789+123'
260
261 Note that setting precision and accurary at the same time is not possible.
262
263 =item t or trace
264
265 This enables a trace mode and is primarily for debugging bigint or
266 Math::BigInt.
267
268 =item l, lib, try or only
269
270 Load a different math lib, see L<Math Library>.
271
272         perl -Mbigint=lib,GMP -e 'print 2 ** 512'
273         perl -Mbigint=try,GMP -e 'print 2 ** 512'
274         perl -Mbigint=only,GMP -e 'print 2 ** 512'
275
276 Currently there is no way to specify more than one library on the command
277 line. This means the following does not work:
278
279         perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
280
281 This will be hopefully fixed soon ;)
282
283 =item v or version
284
285 This prints out the name and version of all modules used and then exits.
286
287         perl -Mbigint=v
288
289 =back
290
291 =head2 Math Library
292
293 Math with the numbers is done (by default) by a module called
294 Math::BigInt::Calc. This is equivalent to saying:
295
296         use bigint lib => 'Calc';
297
298 You can change this by using:
299
300         use bignum lib => 'GMP';
301
302 The following would first try to find Math::BigInt::Foo, then
303 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
304
305         use bigint lib => 'Foo,Math::BigInt::Bar';
306
307 Using C<lib> warns if none of the specified libraries can be found and
308 L<Math::BigInt> did fall back to one of the default libraries.
309 To supress this warning, use C<try> instead:
310
311         use bignum try => 'GMP';
312
313 If you want the code to die instead of falling back, use C<only> instead:
314
315         use bignum only => 'GMP';
316
317 Please see respective module documentation for further details.
318
319 =head2 Internal Format
320
321 The numbers are stored as objects, and their internals might change at anytime,
322 especially between math operations. The objects also might belong to different
323 classes, like Math::BigInt, or Math::BigInt::Lite. Mixing them together, even
324 with normal scalars is not extraordinary, but normal and expected.
325
326 You should not depend on the internal format, all accesses must go through
327 accessor methods. E.g. looking at $x->{sign} is not a good idea since there
328 is no guaranty that the object in question has such a hash key, nor is a hash
329 underneath at all.
330
331 =head2 Sign
332
333 The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
334 You can access it with the sign() method.
335
336 A sign of 'NaN' is used to represent the result when input arguments are not
337 numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
338 minus infinity. You will get '+inf' when dividing a positive number by 0, and
339 '-inf' when dividing any negative number by 0.
340
341 =head2 Methods
342
343 Since all numbers are now objects, you can use all functions that are part of
344 the BigInt API. You can only use the bxxx() notation, and not the fxxx()
345 notation, though. 
346
347 =over 2
348
349 =item inf()
350
351 A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
352 handle bareword C<inf> properly.
353
354 =item NaN()
355
356 A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
357 handle bareword C<NaN> properly.
358
359 =item upgrade()
360
361 Return the class that numbers are upgraded to, is in fact returning
362 C<$Math::BigInt::upgrade>.
363
364 =back
365
366 =head2 MATH LIBRARY
367
368 Math with the numbers is done (by default) by a module called
369
370 =head2 Caveat
371
372 But a warning is in order. When using the following to make a copy of a number,
373 only a shallow copy will be made.
374
375         $x = 9; $y = $x;
376         $x = $y = 7;
377
378 Using the copy or the original with overloaded math is okay, e.g. the
379 following work:
380
381         $x = 9; $y = $x;
382         print $x + 1, " ", $y,"\n";     # prints 10 9
383
384 but calling any method that modifies the number directly will result in
385 B<both> the original and the copy being destroyed:
386         
387         $x = 9; $y = $x;
388         print $x->badd(1), " ", $y,"\n";        # prints 10 10
389         
390         $x = 9; $y = $x;
391         print $x->binc(1), " ", $y,"\n";        # prints 10 10
392         
393         $x = 9; $y = $x;
394         print $x->bmul(2), " ", $y,"\n";        # prints 18 18
395         
396 Using methods that do not modify, but testthe contents works:
397
398         $x = 9; $y = $x;
399         $z = 9 if $x->is_zero();                # works fine
400
401 See the documentation about the copy constructor and C<=> in overload, as
402 well as the documentation in BigInt for further details.
403
404 =head1 MODULES USED
405
406 C<bigint> is just a thin wrapper around various modules of the Math::BigInt
407 family. Think of it as the head of the family, who runs the shop, and orders
408 the others to do the work.
409
410 The following modules are currently used by bigint:
411
412         Math::BigInt::Lite      (for speed, and only if it is loadable)
413         Math::BigInt
414
415 =head1 EXAMPLES
416
417 Some cool command line examples to impress the Python crowd ;) You might want
418 to compare them to the results under -Mbignum or -Mbigrat:
419  
420         perl -Mbigint -le 'print sqrt(33)'
421         perl -Mbigint -le 'print 2*255'
422         perl -Mbigint -le 'print 4.5+2*255'
423         perl -Mbigint -le 'print 3/7 + 5/7 + 8/3'
424         perl -Mbigint -le 'print 123->is_odd()'
425         perl -Mbigint -le 'print log(2)'
426         perl -Mbigint -le 'print 2 ** 0.5'
427         perl -Mbigint=a,65 -le 'print 2 ** 0.2'
428         perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777'
429
430 =head1 LICENSE
431
432 This program is free software; you may redistribute it and/or modify it under
433 the same terms as Perl itself.
434
435 =head1 SEE ALSO
436
437 Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'> and
438 L<bignum> as in C<perl -Mbignum -le 'print sqrt(2)'>.
439
440 L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
441 as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and  L<Math::BigInt::GMP>.
442
443 =head1 AUTHORS
444
445 (C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
446
447 =cut