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