fix warning + carp interaction
[p5sagit/p5-mst-13.2.git] / lib / bignum.pm
1 package bignum;
2 require 5.005;
3
4 $VERSION = '0.10';
5 use Exporter;
6 @ISA =       qw( Exporter );
7 @EXPORT_OK = qw( ); 
8
9 use strict;
10
11 ############################################################################## 
12
13 # These are all alike, and thus faked by AUTOLOAD
14
15 my @faked = qw/round_mode accuracy precision div_scale/;
16 use vars qw/$VERSION $AUTOLOAD $_lite/;         # _lite for testsuite
17
18 sub 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
48 sub 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
60 sub 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
173 1;
174
175 __END__
176
177 =head1 NAME
178
179 bignum - 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
190 All operators (including basic math operations) are overloaded. Integer and
191 floating-point constants are created as proper BigInts or BigFloats,
192 respectively.
193
194 =head2 OPTIONS
195
196 bignum recognizes some options that can be passed while loading it via use.
197 The options can (currently) be either a single letter form, or the long form.
198 The following options exist:
199
200 =over 2
201
202 =item a or accuracy
203
204 This sets the accuracy for all math operations. The argument must be greater
205 than 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
211 This sets the precision for all math operations. The argument can be any
212 integer. Negative values mean a fixed number of digits after the dot, while
213 a positive value rounds to this digit left from the dot. 0 or 1 mean round to
214 integer. 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
220 This enables a trace mode and is primarily for debugging bignum or
221 Math::BigInt/Math::BigFloat.
222
223 =item l or lib
224
225 Load a different math lib, see L<MATH LIBRARY>.
226
227         perl -Mbignum=l,GMP -e 'print 2 ** 512'
228
229 Currently there is no way to specify more than one library on the command
230 line. This will be hopefully fixed soon ;)
231
232 =item v or version
233
234 This 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
240 Math with the numbers is done (by default) by a module called
241 Math::BigInt::Calc. This is equivalent to saying:
242
243         use bignum lib => 'Calc';
244
245 You can change this by using:
246
247         use bignum lib => 'BitVect';
248
249 The following would first try to find Math::BigInt::Foo, then
250 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
251
252         use bignum lib => 'Foo,Math::BigInt::Bar';
253
254 Please see respective module documentation for further details.
255
256 =head2 INTERNAL FORMAT
257
258 The numbers are stored as objects, and their internals might change at anytime,
259 especially between math operations. The objects also might belong to different
260 classes, like Math::BigInt, or Math::BigFLoat. Mixing them together, even
261 with normal scalars is not extraordinary, but normal and expected.
262
263 You should not depend on the internal format, all accesses must go through
264 accessor methods. E.g. looking at $x->{sign} is not a bright idea since there
265 is no guaranty that the object in question has such a hashkey, nor is a hash
266 underneath at all.
267
268 =head2 SIGN
269
270 The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
271 You can access it with the sign() method.
272
273 A sign of 'NaN' is used to represent the result when input arguments are not
274 numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
275 minus 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
280 Since all numbers are now objects, you can use all functions that are part of
281 the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
282 the fxxx() notation, though. This makes it possible that the underlying object
283 might morph into a different class than BigFloat.
284
285 =head1 MODULES USED
286
287 C<bignum> is just a thin wrapper around various modules of the Math::BigInt
288 family. Think of it as the head of the family, who runs the shop, and orders
289 the others to do the work.
290
291 The 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
299 Some 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
312 This program is free software; you may redistribute it and/or modify it under
313 the same terms as Perl itself.
314
315 =head1 SEE ALSO
316
317 Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'>.
318
319 L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
320 as 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