This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge bignum 0.10, from Tels.
[perl5.git] / lib / bignum.pm
CommitLineData
126f3c5f
JH
1package bignum;
2require 5.005;
3
4$VERSION = '0.10';
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';
126 print STDERR "Loading $class";
127 }
128 else
129 {
130 # see if we can find Math::BigInt::Lite
131 if (!defined $a && !defined $p) # rounding won't work to well
132 {
133 eval 'require Math::BigInt::Lite;';
134 if ($@ eq '')
135 {
136 @import = ( ); # :constant in Lite, not MBI
137 Math::BigInt::Lite->import( ':constant' );
138 $_lite= 1; # signal okay
139 }
140 }
141 require Math::BigInt if $_lite == 0; # not already loaded?
142 $class = 'Math::BigInt'; # regardless of MBIL or not
143 }
144 # Math::BigInt::Trace or plain Math::BigInt
145 $class->import(@import, upgrade => $upgrade, lib => $lib);
146
147 if ($trace)
148 {
149 require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace';
150 $downgrade = 'Math::BigInt::Trace';
151 print STDERR "Loading $class";
152 }
153 else
154 {
155 require Math::BigFloat; $class = 'Math::BigFloat';
156 }
157 $class->import(':constant','downgrade',$downgrade);
158
159 bignum->accuracy($a) if defined $a;
160 bignum->precision($p) if defined $p;
161 if ($ver)
162 {
163 print "bignum\t\t\t v$VERSION\n";
164 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
165 print "Math::BigInt\t\t v$Math::BigInt::VERSION";
166 my $config = Math::BigInt->config();
167 print " lib => $config->{lib} v$config->{lib_version}\n";
168 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
169 exit;
170 }
171 }
172
1731;
174
175__END__
176
177=head1 NAME
178
179bignum - Transparent BigNumber support for Perl
180
181=head1 SYNOPSIS
182
183 use bignum;
184
185 $x = 2 + 4.5,"\n"; # BigFloat 6.5
186 print 2 ** 512 * 0.1; # really is what you think it is
187
188=head1 DESCRIPTION
189
190All operators (including basic math operations) are overloaded. Integer and
191floating-point constants are created as proper BigInts or BigFloats,
192respectively.
193
194=head2 OPTIONS
195
196bignum recognizes some options that can be passed while loading it via use.
197The options can (currently) be either a single letter form, or the long form.
198The following options exist:
199
200=over 2
201
202=item a or accuracy
203
204This sets the accuracy for all math operations. The argument must be greater
205than or equal to zero. See Math::BigInt's bround() function for details.
206
207 perl -Mbignum=a,50 -le 'print sqrt(20)'
208
209=item p or precision
210
211This sets the precision for all math operations. The argument can be any
212integer. Negative values mean a fixed number of digits after the dot, while
213a positive value rounds to this digit left from the dot. 0 or 1 mean round to
214integer. See Math::BigInt's bfround() function for details.
215
216 perl -Mbignum=p,-50 -le 'print sqrt(20)'
217
218=item t or trace
219
220This enables a trace mode and is primarily for debugging bignum or
221Math::BigInt/Math::BigFloat.
222
223=item l or lib
224
225Load a different math lib, see L<MATH LIBRARY>.
226
227 perl -Mbignum=l,GMP -e 'print 2 ** 512'
228
229Currently there is no way to specify more than one library on the command
230line. This will be hopefully fixed soon ;)
231
232=item v or version
233
234This prints out the name and version of all modules used and then exits.
235
236 perl -Mbignum=v -e ''
237
238=head2 MATH LIBRARY
239
240Math with the numbers is done (by default) by a module called
241Math::BigInt::Calc. This is equivalent to saying:
242
243 use bignum lib => 'Calc';
244
245You can change this by using:
246
247 use bignum lib => 'BitVect';
248
249The following would first try to find Math::BigInt::Foo, then
250Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
251
252 use bignum lib => 'Foo,Math::BigInt::Bar';
253
254Please see respective module documentation for further details.
255
256=head2 INTERNAL FORMAT
257
258The numbers are stored as objects, and their internals might change at anytime,
259especially between math operations. The objects also might belong to different
260classes, like Math::BigInt, or Math::BigFLoat. Mixing them together, even
261with normal scalars is not extraordinary, but normal and expected.
262
263You should not depend on the internal format, all accesses must go through
264accessor methods. E.g. looking at $x->{sign} is not a bright idea since there
265is no guaranty that the object in question has such a hashkey, nor is a hash
266underneath at all.
267
268=head2 SIGN
269
270The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
271You can access it with the sign() method.
272
273A sign of 'NaN' is used to represent the result when input arguments are not
274numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
275minus infinity. You will get '+inf' when dividing a positive number by 0, and
276'-inf' when dividing any negative number by 0.
277
278=head2 METHODS
279
280Since all numbers are now objects, you can use all functions that are part of
281the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
282the fxxx() notation, though. This makes it possible that the underlying object
283might morph into a different class than BigFloat.
284
285=head1 MODULES USED
286
287C<bignum> is just a thin wrapper around various modules of the Math::BigInt
288family. Think of it as the head of the family, who runs the shop, and orders
289the others to do the work.
290
291The following modules are currently used by bignum:
292
293 Math::BigInt::Lite (for speed, and only if it is loadable)
294 Math::BigInt
295 Math::BigFloat
296
297=head1 EXAMPLES
298
299Some cool command line examples to impress the Python crowd ;)
300
301 perl -Mbignum -le 'print sqrt(33)'
302 perl -Mbignum -le 'print 2*255'
303 perl -Mbignum -le 'print 4.5+2*255'
304 perl -Mbignum -le 'print 3/7 + 5/7 + 8/3'
305 perl -Mbignum -le 'print 123->is_odd()'
306 perl -Mbignum -le 'print log(2)'
307 perl -Mbignum -le 'print 2 ** 0.5'
308 perl -Mbignum=a,65 -le 'print 2 ** 0.2'
309
310=head1 LICENSE
311
312This program is free software; you may redistribute it and/or modify it under
313the same terms as Perl itself.
314
315=head1 SEE ALSO
316
317Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'>.
318
319L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
320as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
321
322=head1 AUTHORS
323
324(C) by Tels L<http://bloodgate.com/> in early 2002.
325
326=cut