This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
new file for #17756
[perl5.git] / lib / bignum.pm
CommitLineData
126f3c5f
JH
1package bignum;
2require 5.005;
3
8f675a64 4$VERSION = '0.11';
126f3c5f
JH
5use Exporter;
6@ISA = qw( Exporter );
7@EXPORT_OK = qw( );
8
9use strict;
10
11##############################################################################
12
13# These are all alike, and thus faked by AUTOLOAD
14
15my @faked = qw/round_mode accuracy precision div_scale/;
16use vars qw/$VERSION $AUTOLOAD $_lite/; # _lite for testsuite
17
18sub AUTOLOAD
19 {
20 my $name = $AUTOLOAD;
21
22 $name =~ s/.*:://; # split package
23 no strict 'refs';
24 foreach my $n (@faked)
25 {
26 if ($n eq $name)
27 {
28 *{"bignum::$name"} = sub
29 {
30 my $self = shift;
31 no strict 'refs';
32 if (defined $_[0])
33 {
34 Math::BigInt->$name($_[0]);
35 Math::BigFloat->$name($_[0]);
36 }
37 return Math::BigInt->$name();
38 };
39 return &$name;
40 }
41 }
42
43 # delayed load of Carp and avoid recursion
44 require Carp;
45 Carp::croak ("Can't call bignum\-\>$name, not a valid method");
46 }
47
48sub upgrade
49 {
50 my $self = shift;
51 no strict 'refs';
52# if (defined $_[0])
53# {
54# $Math::BigInt::upgrade = $_[0];
55# $Math::BigFloat::upgrade = $_[0];
56# }
57 return $Math::BigInt::upgrade;
58 }
59
60sub import
61 {
62 my $self = shift;
63
64 # some defaults
65 my $lib = 'Calc';
66 my $upgrade = 'Math::BigFloat';
67 my $downgrade = 'Math::BigInt';
68
69 my @import = ( ':constant' ); # drive it w/ constant
70 my @a = @_; my $l = scalar @_; my $j = 0;
71 my ($ver,$trace); # version? trace?
72 my ($a,$p); # accuracy, precision
73 for ( my $i = 0; $i < $l ; $i++,$j++ )
74 {
75 if ($_[$i] eq 'upgrade')
76 {
77 # this causes upgrading
78 $upgrade = $_[$i+1]; # or undef to disable
79 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
80 splice @a, $j, $s; $j -= $s; $i++;
81 }
82 elsif ($_[$i] eq 'downgrade')
83 {
84 # this causes downgrading
85 $downgrade = $_[$i+1]; # or undef to disable
86 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
87 splice @a, $j, $s; $j -= $s; $i++;
88 }
89 elsif ($_[$i] =~ /^(l|lib)$/)
90 {
91 # this causes a different low lib to take care...
92 $lib = $_[$i+1] || '';
93 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
94 splice @a, $j, $s; $j -= $s; $i++;
95 }
96 elsif ($_[$i] =~ /^(a|accuracy)$/)
97 {
98 $a = $_[$i+1];
99 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
100 splice @a, $j, $s; $j -= $s; $i++;
101 }
102 elsif ($_[$i] =~ /^(p|precision)$/)
103 {
104 $p = $_[$i+1];
105 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
106 splice @a, $j, $s; $j -= $s; $i++;
107 }
108 elsif ($_[$i] =~ /^(v|version)$/)
109 {
110 $ver = 1;
111 splice @a, $j, 1; $j --;
112 }
113 elsif ($_[$i] =~ /^(t|trace)$/)
114 {
115 $trace = 1;
116 splice @a, $j, 1; $j --;
117 }
118 else { die "unknown option $_[$i]"; }
119 }
120 my $class;
121 $_lite = 0; # using M::BI::L ?
122 if ($trace)
123 {
124 require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
125 $upgrade = 'Math::BigFloat::Trace';
126f3c5f
JH
126 }
127 else
128 {
129 # see if we can find Math::BigInt::Lite
130 if (!defined $a && !defined $p) # rounding won't work to well
131 {
132 eval 'require Math::BigInt::Lite;';
133 if ($@ eq '')
134 {
135 @import = ( ); # :constant in Lite, not MBI
136 Math::BigInt::Lite->import( ':constant' );
137 $_lite= 1; # signal okay
138 }
139 }
140 require Math::BigInt if $_lite == 0; # not already loaded?
141 $class = 'Math::BigInt'; # regardless of MBIL or not
142 }
143 # Math::BigInt::Trace or plain Math::BigInt
144 $class->import(@import, upgrade => $upgrade, lib => $lib);
145
146 if ($trace)
147 {
148 require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace';
149 $downgrade = 'Math::BigInt::Trace';
126f3c5f
JH
150 }
151 else
152 {
153 require Math::BigFloat; $class = 'Math::BigFloat';
154 }
155 $class->import(':constant','downgrade',$downgrade);
156
157 bignum->accuracy($a) if defined $a;
158 bignum->precision($p) if defined $p;
159 if ($ver)
160 {
161 print "bignum\t\t\t v$VERSION\n";
162 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
163 print "Math::BigInt\t\t v$Math::BigInt::VERSION";
164 my $config = Math::BigInt->config();
165 print " lib => $config->{lib} v$config->{lib_version}\n";
166 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
167 exit;
168 }
169 }
170
1711;
172
173__END__
174
175=head1 NAME
176
177bignum - Transparent BigNumber support for Perl
178
179=head1 SYNOPSIS
180
181 use bignum;
182
183 $x = 2 + 4.5,"\n"; # BigFloat 6.5
184 print 2 ** 512 * 0.1; # really is what you think it is
185
186=head1 DESCRIPTION
187
188All operators (including basic math operations) are overloaded. Integer and
189floating-point constants are created as proper BigInts or BigFloats,
190respectively.
191
192=head2 OPTIONS
193
194bignum recognizes some options that can be passed while loading it via use.
195The options can (currently) be either a single letter form, or the long form.
196The following options exist:
197
198=over 2
199
200=item a or accuracy
201
202This sets the accuracy for all math operations. The argument must be greater
203than or equal to zero. See Math::BigInt's bround() function for details.
204
205 perl -Mbignum=a,50 -le 'print sqrt(20)'
206
207=item p or precision
208
209This sets the precision for all math operations. The argument can be any
210integer. Negative values mean a fixed number of digits after the dot, while
211a positive value rounds to this digit left from the dot. 0 or 1 mean round to
212integer. See Math::BigInt's bfround() function for details.
213
214 perl -Mbignum=p,-50 -le 'print sqrt(20)'
215
216=item t or trace
217
218This enables a trace mode and is primarily for debugging bignum or
219Math::BigInt/Math::BigFloat.
220
221=item l or lib
222
223Load a different math lib, see L<MATH LIBRARY>.
224
225 perl -Mbignum=l,GMP -e 'print 2 ** 512'
226
227Currently there is no way to specify more than one library on the command
228line. This will be hopefully fixed soon ;)
229
230=item v or version
231
232This prints out the name and version of all modules used and then exits.
233
234 perl -Mbignum=v -e ''
235
236=head2 MATH LIBRARY
237
238Math with the numbers is done (by default) by a module called
239Math::BigInt::Calc. This is equivalent to saying:
240
241 use bignum lib => 'Calc';
242
243You can change this by using:
244
245 use bignum lib => 'BitVect';
246
247The following would first try to find Math::BigInt::Foo, then
248Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
249
250 use bignum lib => 'Foo,Math::BigInt::Bar';
251
252Please see respective module documentation for further details.
253
254=head2 INTERNAL FORMAT
255
256The numbers are stored as objects, and their internals might change at anytime,
257especially between math operations. The objects also might belong to different
258classes, like Math::BigInt, or Math::BigFLoat. Mixing them together, even
259with normal scalars is not extraordinary, but normal and expected.
260
261You should not depend on the internal format, all accesses must go through
262accessor methods. E.g. looking at $x->{sign} is not a bright idea since there
263is no guaranty that the object in question has such a hashkey, nor is a hash
264underneath at all.
265
266=head2 SIGN
267
268The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
269You can access it with the sign() method.
270
271A sign of 'NaN' is used to represent the result when input arguments are not
272numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
273minus infinity. You will get '+inf' when dividing a positive number by 0, and
274'-inf' when dividing any negative number by 0.
275
276=head2 METHODS
277
278Since all numbers are now objects, you can use all functions that are part of
279the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
280the fxxx() notation, though. This makes it possible that the underlying object
281might morph into a different class than BigFloat.
282
283=head1 MODULES USED
284
285C<bignum> is just a thin wrapper around various modules of the Math::BigInt
286family. Think of it as the head of the family, who runs the shop, and orders
287the others to do the work.
288
289The following modules are currently used by bignum:
290
291 Math::BigInt::Lite (for speed, and only if it is loadable)
292 Math::BigInt
293 Math::BigFloat
294
295=head1 EXAMPLES
296
297Some cool command line examples to impress the Python crowd ;)
298
299 perl -Mbignum -le 'print sqrt(33)'
300 perl -Mbignum -le 'print 2*255'
301 perl -Mbignum -le 'print 4.5+2*255'
302 perl -Mbignum -le 'print 3/7 + 5/7 + 8/3'
303 perl -Mbignum -le 'print 123->is_odd()'
304 perl -Mbignum -le 'print log(2)'
305 perl -Mbignum -le 'print 2 ** 0.5'
306 perl -Mbignum=a,65 -le 'print 2 ** 0.2'
307
308=head1 LICENSE
309
310This program is free software; you may redistribute it and/or modify it under
311the same terms as Perl itself.
312
313=head1 SEE ALSO
314
315Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'>.
316
317L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
318as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
319
320=head1 AUTHORS
321
322(C) by Tels L<http://bloodgate.com/> in early 2002.
323
324=cut