This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #41587] [PATCH] 5.8.8 make sure we get the proper ldflags on libperl.so
[perl5.git] / lib / bigint.pm
1 package bigint;
2 use 5.006002;
3
4 $VERSION = '0.09';
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 = '';
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)$/)
127       {
128       # this causes a different low lib to take care...
129       $lib = $_[$i+1] || '';
130       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
131       splice @a, $j, $s; $j -= $s; $i++;
132       }
133     elsif ($_[$i] =~ /^(a|accuracy)$/)
134       {
135       $a = $_[$i+1];
136       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
137       splice @a, $j, $s; $j -= $s; $i++;
138       }
139     elsif ($_[$i] =~ /^(p|precision)$/)
140       {
141       $p = $_[$i+1];
142       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
143       splice @a, $j, $s; $j -= $s; $i++;
144       }
145     elsif ($_[$i] =~ /^(v|version)$/)
146       {
147       $ver = 1;
148       splice @a, $j, 1; $j --;
149       }
150     elsif ($_[$i] =~ /^(t|trace)$/)
151       {
152       $trace = 1;
153       splice @a, $j, 1; $j --;
154       }
155     else { die "unknown option $_[$i]"; }
156     }
157   my $class;
158   $_lite = 0;                                   # using M::BI::L ?
159   if ($trace)
160     {
161     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
162     }
163   else
164     {
165     # see if we can find Math::BigInt::Lite
166     if (!defined $a && !defined $p)             # rounding won't work to well
167       {
168       eval 'require Math::BigInt::Lite;';
169       if ($@ eq '')
170         {
171         @import = ( );                          # :constant in Lite, not MBI
172         Math::BigInt::Lite->import( ':constant' );
173         $_lite= 1;                              # signal okay
174         }
175       }
176     require Math::BigInt if $_lite == 0;        # not already loaded?
177     $class = 'Math::BigInt';                    # regardless of MBIL or not
178     }
179   push @import, 'try' => $lib if $lib ne '';
180   # Math::BigInt::Trace or plain Math::BigInt
181   $class->import(@import);
182
183   bigint->accuracy($a) if defined $a;
184   bigint->precision($p) if defined $p;
185   if ($ver)
186     {
187     print "bigint\t\t\t v$VERSION\n";
188     print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
189     print "Math::BigInt\t\t v$Math::BigInt::VERSION";
190     my $config = Math::BigInt->config();
191     print " lib => $config->{lib} v$config->{lib_version}\n";
192     exit;
193     }
194   # we take care of floating point constants, since BigFloat isn't available
195   # and BigInt doesn't like them:
196   overload::constant float => sub { Math::BigInt->new( _float_constant(shift) ); };
197   # Take care of octal/hexadecimal constants
198   overload::constant binary => sub { _binary_constant(shift) };
199
200   $self->export_to_level(1,$self,@a);           # export inf and NaN
201   }
202
203 sub inf () { Math::BigInt->binf(); }
204 sub NaN () { Math::BigInt->bnan(); }
205
206 1;
207
208 __END__
209
210 =head1 NAME
211
212 bigint - Transparent BigInteger support for Perl
213
214 =head1 SYNOPSIS
215
216   use bigint;
217
218   $x = 2 + 4.5,"\n";                    # BigInt 6
219   print 2 ** 512,"\n";                  # really is what you think it is
220   print inf + 42,"\n";                  # inf
221   print NaN * 7,"\n";                   # NaN
222
223 =head1 DESCRIPTION
224
225 All operators (including basic math operations) are overloaded. Integer
226 constants are created as proper BigInts.
227
228 Floating point constants are truncated to integer. All results are also
229 truncated.
230
231 =head2 Options
232
233 bigint recognizes some options that can be passed while loading it via use.
234 The options can (currently) be either a single letter form, or the long form.
235 The following options exist:
236
237 =over 2
238
239 =item a or accuracy
240
241 This sets the accuracy for all math operations. The argument must be greater
242 than or equal to zero. See Math::BigInt's bround() function for details.
243
244         perl -Mbigint=a,2 -le 'print 12345+1'
245
246 Note that setting precision and accurary at the same time is not possible.
247
248 =item p or precision
249
250 This sets the precision for all math operations. The argument can be any
251 integer. Negative values mean a fixed number of digits after the dot, and
252 are <B>ignored</B> since all operations happen in integer space.
253 A positive value rounds to this digit left from the dot. 0 or 1 mean round to
254 integer and are ignore like negative values.
255
256 See Math::BigInt's bfround() function for details.
257
258         perl -Mbignum=p,5 -le 'print 123456789+123'
259
260 Note that setting precision and accurary at the same time is not possible.
261
262 =item t or trace
263
264 This enables a trace mode and is primarily for debugging bigint or
265 Math::BigInt.
266
267 =item l or lib
268
269 Load a different math lib, see L<MATH LIBRARY>.
270
271         perl -Mbigint=l,GMP -e 'print 2 ** 512'
272
273 Currently there is no way to specify more than one library on the command
274 line. This means the following does not work:
275
276         perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
277
278 This will be hopefully fixed soon ;)
279
280 =item v or version
281
282 This prints out the name and version of all modules used and then exits.
283
284         perl -Mbigint=v
285
286 =back
287
288 =head2 Math Library
289
290 Math with the numbers is done (by default) by a module called
291 Math::BigInt::Calc. This is equivalent to saying:
292
293         use bigint lib => 'Calc';
294
295 You can change this by using:
296
297         use bigint lib => 'BitVect';
298
299 The following would first try to find Math::BigInt::Foo, then
300 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
301
302         use bigint lib => 'Foo,Math::BigInt::Bar';
303
304 Please see respective module documentation for further details.
305
306 =head2 Internal Format
307
308 The numbers are stored as objects, and their internals might change at anytime,
309 especially between math operations. The objects also might belong to different
310 classes, like Math::BigInt, or Math::BigInt::Lite. Mixing them together, even
311 with normal scalars is not extraordinary, but normal and expected.
312
313 You should not depend on the internal format, all accesses must go through
314 accessor methods. E.g. looking at $x->{sign} is not a good idea since there
315 is no guaranty that the object in question has such a hash key, nor is a hash
316 underneath at all.
317
318 =head2 Sign
319
320 The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
321 You can access it with the sign() method.
322
323 A sign of 'NaN' is used to represent the result when input arguments are not
324 numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
325 minus infinity. You will get '+inf' when dividing a positive number by 0, and
326 '-inf' when dividing any negative number by 0.
327
328 =head2 Methods
329
330 Since all numbers are now objects, you can use all functions that are part of
331 the BigInt API. You can only use the bxxx() notation, and not the fxxx()
332 notation, though. 
333
334 =over 2
335
336 =item inf()
337
338 A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
339 handle bareword C<inf> properly.
340
341 =item NaN()
342
343 A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
344 handle bareword C<NaN> properly.
345
346 =item upgrade()
347
348 Return the class that numbers are upgraded to, is in fact returning
349 C<$Math::BigInt::upgrade>.
350
351 =back
352
353 =head2 MATH LIBRARY
354
355 Math with the numbers is done (by default) by a module called
356
357 =head2 Caveat
358
359 But a warning is in order. When using the following to make a copy of a number,
360 only a shallow copy will be made.
361
362         $x = 9; $y = $x;
363         $x = $y = 7;
364
365 Using the copy or the original with overloaded math is okay, e.g. the
366 following work:
367
368         $x = 9; $y = $x;
369         print $x + 1, " ", $y,"\n";     # prints 10 9
370
371 but calling any method that modifies the number directly will result in
372 B<both> the original and the copy being destroyed:
373         
374         $x = 9; $y = $x;
375         print $x->badd(1), " ", $y,"\n";        # prints 10 10
376         
377         $x = 9; $y = $x;
378         print $x->binc(1), " ", $y,"\n";        # prints 10 10
379         
380         $x = 9; $y = $x;
381         print $x->bmul(2), " ", $y,"\n";        # prints 18 18
382         
383 Using methods that do not modify, but testthe contents works:
384
385         $x = 9; $y = $x;
386         $z = 9 if $x->is_zero();                # works fine
387
388 See the documentation about the copy constructor and C<=> in overload, as
389 well as the documentation in BigInt for further details.
390
391 =head1 MODULES USED
392
393 C<bigint> is just a thin wrapper around various modules of the Math::BigInt
394 family. Think of it as the head of the family, who runs the shop, and orders
395 the others to do the work.
396
397 The following modules are currently used by bigint:
398
399         Math::BigInt::Lite      (for speed, and only if it is loadable)
400         Math::BigInt
401
402 =head1 EXAMPLES
403
404 Some cool command line examples to impress the Python crowd ;) You might want
405 to compare them to the results under -Mbignum or -Mbigrat:
406  
407         perl -Mbigint -le 'print sqrt(33)'
408         perl -Mbigint -le 'print 2*255'
409         perl -Mbigint -le 'print 4.5+2*255'
410         perl -Mbigint -le 'print 3/7 + 5/7 + 8/3'
411         perl -Mbigint -le 'print 123->is_odd()'
412         perl -Mbigint -le 'print log(2)'
413         perl -Mbigint -le 'print 2 ** 0.5'
414         perl -Mbigint=a,65 -le 'print 2 ** 0.2'
415         perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777'
416
417 =head1 LICENSE
418
419 This program is free software; you may redistribute it and/or modify it under
420 the same terms as Perl itself.
421
422 =head1 SEE ALSO
423
424 Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'> and
425 L<bignum> as in C<perl -Mbignum -le 'print sqrt(2)'>.
426
427 L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
428 as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and  L<Math::BigInt::GMP>.
429
430 =head1 AUTHORS
431
432 (C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
433
434 =cut