Upgrage to bignum-0.21 and Math-BigRat-0.19
[p5sagit/p5-mst-13.2.git] / lib / bigint.pm
CommitLineData
126f3c5f 1package bigint;
95a2d02c 2use 5.006002;
126f3c5f 3
bd49aa09 4$VERSION = '0.10';
126f3c5f 5use Exporter;
b4bc5691 6@ISA = qw( Exporter );
7@EXPORT_OK = qw( );
8@EXPORT = qw( inf NaN );
126f3c5f 9
10use strict;
11use overload;
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 *{"bigint::$name"} = sub
31 {
32 my $self = shift;
33 no strict 'refs';
34 if (defined $_[0])
35 {
990fb837 36 return Math::BigInt->$name($_[0]);
126f3c5f 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
49sub upgrade
50 {
51 my $self = shift;
52 no strict 'refs';
53# if (defined $_[0])
54# {
55# $Math::BigInt::upgrade = $_[0];
56# }
95a2d02c 57 $Math::BigInt::upgrade;
126f3c5f 58 }
59
95a2d02c 60sub _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
73sub _float_constant
126f3c5f 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 }
9b924220 89 my ($mis,$miv,$mfv,$es,$ev) = Math::BigInt::_split($float);
126f3c5f 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);
95a2d02c 110 $sign.$$miv.$mfv; # 123.45e+1 => 1234
126f3c5f 111 }
112
113sub import
114 {
115 my $self = shift;
116
117 # some defaults
bd49aa09 118 my $lib = ''; my $lib_kind = 'try';
126f3c5f 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 {
bd49aa09 126 if ($_[$i] =~ /^(l|lib|try|only)$/)
126f3c5f 127 {
128 # this causes a different low lib to take care...
bd49aa09 129 $lib_kind = $1; $lib_kind = 'lib' if $lib_kind eq 'l';
126f3c5f 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';
126f3c5f 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
233f7bc0 179 }
bd49aa09 180 push @import, $lib_kind => $lib if $lib ne '';
126f3c5f 181 # Math::BigInt::Trace or plain Math::BigInt
233f7bc0 182 $class->import(@import);
126f3c5f 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:
95a2d02c 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) };
b4bc5691 200
201 $self->export_to_level(1,$self,@a); # export inf and NaN
126f3c5f 202 }
203
b4bc5691 204sub inf () { Math::BigInt->binf(); }
205sub NaN () { Math::BigInt->bnan(); }
206
126f3c5f 2071;
208
209__END__
210
211=head1 NAME
212
b4bc5691 213bigint - Transparent BigInteger support for Perl
126f3c5f 214
215=head1 SYNOPSIS
216
f9156151 217 use bigint;
126f3c5f 218
219 $x = 2 + 4.5,"\n"; # BigInt 6
b4bc5691 220 print 2 ** 512,"\n"; # really is what you think it is
221 print inf + 42,"\n"; # inf
222 print NaN * 7,"\n"; # NaN
126f3c5f 223
224=head1 DESCRIPTION
225
226All operators (including basic math operations) are overloaded. Integer
227constants are created as proper BigInts.
228
229Floating point constants are truncated to integer. All results are also
990fb837 230truncated.
126f3c5f 231
b68b7ab1 232=head2 Options
126f3c5f 233
234bigint recognizes some options that can be passed while loading it via use.
235The options can (currently) be either a single letter form, or the long form.
236The following options exist:
237
238=over 2
239
240=item a or accuracy
241
242This sets the accuracy for all math operations. The argument must be greater
243than or equal to zero. See Math::BigInt's bround() function for details.
244
245 perl -Mbigint=a,2 -le 'print 12345+1'
246
95a2d02c 247Note that setting precision and accurary at the same time is not possible.
248
126f3c5f 249=item p or precision
250
251This sets the precision for all math operations. The argument can be any
252integer. Negative values mean a fixed number of digits after the dot, and
253are <B>ignored</B> since all operations happen in integer space.
254A positive value rounds to this digit left from the dot. 0 or 1 mean round to
255integer and are ignore like negative values.
256
257See Math::BigInt's bfround() function for details.
258
259 perl -Mbignum=p,5 -le 'print 123456789+123'
260
95a2d02c 261Note that setting precision and accurary at the same time is not possible.
262
126f3c5f 263=item t or trace
264
265This enables a trace mode and is primarily for debugging bigint or
266Math::BigInt.
267
bd49aa09 268=item l, lib, try or only
126f3c5f 269
bd49aa09 270Load a different math lib, see L<Math Library>.
126f3c5f 271
bd49aa09 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'
126f3c5f 275
276Currently there is no way to specify more than one library on the command
95a2d02c 277line. This means the following does not work:
278
279 perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
280
281This will be hopefully fixed soon ;)
126f3c5f 282
283=item v or version
284
285This prints out the name and version of all modules used and then exits.
286
b68b7ab1 287 perl -Mbigint=v
126f3c5f 288
95a2d02c 289=back
290
b68b7ab1 291=head2 Math Library
126f3c5f 292
293Math with the numbers is done (by default) by a module called
294Math::BigInt::Calc. This is equivalent to saying:
295
296 use bigint lib => 'Calc';
297
298You can change this by using:
299
bd49aa09 300 use bignum lib => 'GMP';
126f3c5f 301
302The following would first try to find Math::BigInt::Foo, then
303Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
304
305 use bigint lib => 'Foo,Math::BigInt::Bar';
306
bd49aa09 307Using C<lib> warns if none of the specified libraries can be found and
308L<Math::BigInt> did fall back to one of the default libraries.
309To supress this warning, use C<try> instead:
310
311 use bignum try => 'GMP';
312
313If you want the code to die instead of falling back, use C<only> instead:
314
315 use bignum only => 'GMP';
316
126f3c5f 317Please see respective module documentation for further details.
318
b68b7ab1 319=head2 Internal Format
126f3c5f 320
321The numbers are stored as objects, and their internals might change at anytime,
322especially between math operations. The objects also might belong to different
323classes, like Math::BigInt, or Math::BigInt::Lite. Mixing them together, even
324with normal scalars is not extraordinary, but normal and expected.
325
326You should not depend on the internal format, all accesses must go through
990fb837 327accessor methods. E.g. looking at $x->{sign} is not a good idea since there
126f3c5f 328is no guaranty that the object in question has such a hash key, nor is a hash
329underneath at all.
330
b68b7ab1 331=head2 Sign
126f3c5f 332
b68b7ab1 333The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
126f3c5f 334You can access it with the sign() method.
335
336A sign of 'NaN' is used to represent the result when input arguments are not
337numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
338minus infinity. You will get '+inf' when dividing a positive number by 0, and
339'-inf' when dividing any negative number by 0.
340
b68b7ab1 341=head2 Methods
126f3c5f 342
343Since all numbers are now objects, you can use all functions that are part of
344the BigInt API. You can only use the bxxx() notation, and not the fxxx()
345notation, though.
346
95a2d02c 347=over 2
348
349=item inf()
350
351A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
352handle bareword C<inf> properly.
353
354=item NaN()
355
356A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
357handle bareword C<NaN> properly.
358
359=item upgrade()
360
361Return the class that numbers are upgraded to, is in fact returning
362C<$Math::BigInt::upgrade>.
363
364=back
365
366=head2 MATH LIBRARY
367
368Math with the numbers is done (by default) by a module called
369
b68b7ab1 370=head2 Caveat
990fb837 371
372But a warning is in order. When using the following to make a copy of a number,
373only a shallow copy will be made.
374
375 $x = 9; $y = $x;
376 $x = $y = 7;
377
378Using the copy or the original with overloaded math is okay, e.g. the
379following work:
380
381 $x = 9; $y = $x;
382 print $x + 1, " ", $y,"\n"; # prints 10 9
383
384but calling any method that modifies the number directly will result in
3c4b39be 385B<both> the original and the copy being destroyed:
990fb837 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
396Using 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
401See the documentation about the copy constructor and C<=> in overload, as
402well as the documentation in BigInt for further details.
403
126f3c5f 404=head1 MODULES USED
405
406C<bigint> is just a thin wrapper around various modules of the Math::BigInt
407family. Think of it as the head of the family, who runs the shop, and orders
408the others to do the work.
409
410The 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
417Some cool command line examples to impress the Python crowd ;) You might want
418to 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'
95a2d02c 428 perl -Mbignum=a,65,l,GMP -le 'print 7 ** 7777'
126f3c5f 429
430=head1 LICENSE
431
432This program is free software; you may redistribute it and/or modify it under
433the same terms as Perl itself.
434
435=head1 SEE ALSO
436
437Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'> and
438L<bignum> as in C<perl -Mbignum -le 'print sqrt(2)'>.
439
440L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
441as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
442
443=head1 AUTHORS
444
95a2d02c 445(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
126f3c5f 446
447=cut