source: for-distributions/trunk/bin/windows/perl/lib/bignum.pm@ 14489

Last change on this file since 14489 was 14489, checked in by oranfry, 17 years ago

upgrading to perl 5.8

File size: 13.8 KB
Line 
1package bignum;
2require 5.005;
3
4$VERSION = '0.17';
5use Exporter;
6@EXPORT_OK = qw( );
7@EXPORT = qw( inf NaN );
8@ISA = qw( Exporter );
9
10use strict;
11
12##############################################################################
13
14# These are all alike, and thus faked by AUTOLOAD
15
16my @faked = qw/round_mode accuracy precision div_scale/;
17use vars qw/$VERSION $AUTOLOAD $_lite/; # _lite for testsuite
18
19sub AUTOLOAD
20 {
21 my $name = $AUTOLOAD;
22
23 $name =~ s/.*:://; # split package
24 no strict 'refs';
25 foreach my $n (@faked)
26 {
27 if ($n eq $name)
28 {
29 *{"bignum::$name"} = sub
30 {
31 my $self = shift;
32 no strict 'refs';
33 if (defined $_[0])
34 {
35 Math::BigInt->$name($_[0]);
36 return Math::BigFloat->$name($_[0]);
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 bignum\-\>$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# $Math::BigFloat::upgrade = $_[0];
57# }
58 return $Math::BigInt::upgrade;
59 }
60
61sub import
62 {
63 my $self = shift;
64
65 # some defaults
66 my $lib = '';
67 my $upgrade = 'Math::BigFloat';
68 my $downgrade = 'Math::BigInt';
69
70 my @import = ( ':constant' ); # drive it w/ constant
71 my @a = @_; my $l = scalar @_; my $j = 0;
72 my ($ver,$trace); # version? trace?
73 my ($a,$p); # accuracy, precision
74 for ( my $i = 0; $i < $l ; $i++,$j++ )
75 {
76 if ($_[$i] eq 'upgrade')
77 {
78 # this causes upgrading
79 $upgrade = $_[$i+1]; # or undef to disable
80 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
81 splice @a, $j, $s; $j -= $s; $i++;
82 }
83 elsif ($_[$i] eq 'downgrade')
84 {
85 # this causes downgrading
86 $downgrade = $_[$i+1]; # or undef to disable
87 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
88 splice @a, $j, $s; $j -= $s; $i++;
89 }
90 elsif ($_[$i] =~ /^(l|lib)$/)
91 {
92 # this causes a different low lib to take care...
93 $lib = $_[$i+1] || '';
94 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
95 splice @a, $j, $s; $j -= $s; $i++;
96 }
97 elsif ($_[$i] =~ /^(a|accuracy)$/)
98 {
99 $a = $_[$i+1];
100 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
101 splice @a, $j, $s; $j -= $s; $i++;
102 }
103 elsif ($_[$i] =~ /^(p|precision)$/)
104 {
105 $p = $_[$i+1];
106 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
107 splice @a, $j, $s; $j -= $s; $i++;
108 }
109 elsif ($_[$i] =~ /^(v|version)$/)
110 {
111 $ver = 1;
112 splice @a, $j, 1; $j --;
113 }
114 elsif ($_[$i] =~ /^(t|trace)$/)
115 {
116 $trace = 1;
117 splice @a, $j, 1; $j --;
118 }
119 else { die "unknown option $_[$i]"; }
120 }
121 my $class;
122 $_lite = 0; # using M::BI::L ?
123 if ($trace)
124 {
125 require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
126 $upgrade = 'Math::BigFloat::Trace';
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 push @import, 'lib' => $lib if $lib ne '';
145 # Math::BigInt::Trace or plain Math::BigInt
146 $class->import(@import, upgrade => $upgrade);
147
148 if ($trace)
149 {
150 require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace';
151 $downgrade = 'Math::BigInt::Trace';
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 $self->export_to_level(1,$self,@a); # export inf and NaN
172 }
173
174sub inf () { Math::BigInt->binf(); }
175sub NaN () { Math::BigInt->bnan(); }
176
1771;
178
179__END__
180
181=head1 NAME
182
183bignum - Transparent BigNumber support for Perl
184
185=head1 SYNOPSIS
186
187 use bignum;
188
189 $x = 2 + 4.5,"\n"; # BigFloat 6.5
190 print 2 ** 512 * 0.1,"\n"; # really is what you think it is
191 print inf * inf,"\n"; # prints inf
192 print NaN * 3,"\n"; # prints NaN
193
194=head1 DESCRIPTION
195
196All operators (including basic math operations) are overloaded. Integer and
197floating-point constants are created as proper BigInts or BigFloats,
198respectively.
199
200If you do
201
202 use bignum;
203
204at the top of your script, Math::BigFloat and Math::BigInt will be loaded
205and any constant number will be converted to an object (Math::BigFloat for
206floats like 3.1415 and Math::BigInt for integers like 1234).
207
208So, the following line:
209
210 $x = 1234;
211
212creates actually a Math::BigInt and stores a reference to in $x.
213This happens transparently and behind your back, so to speak.
214
215You can see this with the following:
216
217 perl -Mbignum -le 'print ref(1234)'
218
219Don't worry if it says Math::BigInt::Lite, bignum and friends will use Lite
220if it is installed since it is faster for some operations. It will be
221automatically upgraded to BigInt whenever neccessary:
222
223 perl -Mbignum -le 'print ref(2**255)'
224
225This also means it is a bad idea to check for some specific package, since
226the actual contents of $x might be something unexpected. Due to the
227transparent way of bignum C<ref()> should not be neccessary, anyway.
228
229Since Math::BigInt and BigFloat also overload the normal math operations,
230the following line will still work:
231
232 perl -Mbignum -le 'print ref(1234+1234)'
233
234Since numbers are actually objects, you can call all the usual methods from
235BigInt/BigFloat on them. This even works to some extent on expressions:
236
237 perl -Mbignum -le '$x = 1234; print $x->bdec()'
238 perl -Mbignum -le 'print 1234->binc();'
239 perl -Mbignum -le 'print 1234->binc->badd(6);'
240 perl -Mbignum -le 'print +(1234)->binc()'
241
242(Note that print doesn't do what you expect if the expression starts with
243'(' hence the C<+>)
244
245You can even chain the operations together as usual:
246
247 perl -Mbignum -le 'print 1234->binc->badd(6);'
248 1241
249
250Under bignum (or bigint or bigrat), Perl will "upgrade" the numbers
251appropriately. This means that:
252
253 perl -Mbignum -le 'print 1234+4.5'
254 1238.5
255
256will work correctly. These mixed cases don't do always work when using
257Math::BigInt or Math::BigFloat alone, or at least not in the way normal Perl
258scalars work.
259
260If you do want to work with large integers like under C<use integer;>, try
261C<use bigint;>:
262
263 perl -Mbigint -le 'print 1234.5+4.5'
264 1238
265
266There is also C<use bigrat;> which gives you big rationals:
267
268 perl -Mbigrat -le 'print 1234+4.1'
269 12381/10
270
271The entire upgrading/downgrading is still experimental and might not work
272as you expect or may even have bugs.
273
274You might get errors like this:
275
276 Can't use an undefined value as an ARRAY reference at
277 /usr/local/lib/perl5/5.8.0/Math/BigInt/Calc.pm line 864
278
279This means somewhere a routine got a BigFloat/Lite but expected a BigInt (or
280vice versa) and the upgrade/downgrad path was missing. This is a bug, please
281report it so that we can fix it.
282
283You might consider using just Math::BigInt or Math::BigFloat, since they
284allow you finer control over what get's done in which module/space. For
285instance, simple loop counters will be Math::BigInts under C<use bignum;> and
286this is slower than keeping them as Perl scalars:
287
288 perl -Mbignum -le 'for ($i = 0; $i < 10; $i++) { print ref($i); }'
289
290Please note the following does not work as expected (prints nothing), since
291overloading of '..' is not yet possible in Perl (as of v5.8.0):
292
293 perl -Mbignum -le 'for (1..2) { print ref($_); }'
294
295=head2 Options
296
297bignum recognizes some options that can be passed while loading it via use.
298The options can (currently) be either a single letter form, or the long form.
299The following options exist:
300
301=over 2
302
303=item a or accuracy
304
305This sets the accuracy for all math operations. The argument must be greater
306than or equal to zero. See Math::BigInt's bround() function for details.
307
308 perl -Mbignum=a,50 -le 'print sqrt(20)'
309
310=item p or precision
311
312This sets the precision for all math operations. The argument can be any
313integer. Negative values mean a fixed number of digits after the dot, while
314a positive value rounds to this digit left from the dot. 0 or 1 mean round to
315integer. See Math::BigInt's bfround() function for details.
316
317 perl -Mbignum=p,-50 -le 'print sqrt(20)'
318
319=item t or trace
320
321This enables a trace mode and is primarily for debugging bignum or
322Math::BigInt/Math::BigFloat.
323
324=item l or lib
325
326Load a different math lib, see L<MATH LIBRARY>.
327
328 perl -Mbignum=l,GMP -e 'print 2 ** 512'
329
330Currently there is no way to specify more than one library on the command
331line. This will be hopefully fixed soon ;)
332
333=item v or version
334
335This prints out the name and version of all modules used and then exits.
336
337 perl -Mbignum=v
338
339=head2 Methods
340
341Beside import() and AUTOLOAD() there are only a few other methods.
342
343Since all numbers are now objects, you can use all functions that are part of
344the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
345the fxxx() notation, though. This makes it possible that the underlying object
346might morph into a different class than BigFloat.
347
348=head2 Caveat
349
350But a warning is in order. When using the following to make a copy of a number,
351only a shallow copy will be made.
352
353 $x = 9; $y = $x;
354 $x = $y = 7;
355
356If you want to make a real copy, use the following:
357
358 $y = $x->copy();
359
360Using the copy or the original with overloaded math is okay, e.g. the
361following work:
362
363 $x = 9; $y = $x;
364 print $x + 1, " ", $y,"\n"; # prints 10 9
365
366but calling any method that modifies the number directly will result in
367B<both> the original and the copy beeing destroyed:
368
369 $x = 9; $y = $x;
370 print $x->badd(1), " ", $y,"\n"; # prints 10 10
371
372 $x = 9; $y = $x;
373 print $x->binc(1), " ", $y,"\n"; # prints 10 10
374
375 $x = 9; $y = $x;
376 print $x->bmul(2), " ", $y,"\n"; # prints 18 18
377
378Using methods that do not modify, but testthe contents works:
379
380 $x = 9; $y = $x;
381 $z = 9 if $x->is_zero(); # works fine
382
383See the documentation about the copy constructor and C<=> in overload, as
384well as the documentation in BigInt for further details.
385
386=over 2
387
388=item inf()
389
390A shortcut to return Math::BigInt->binf(). Usefull because Perl does not always
391handle bareword C<inf> properly.
392
393=item NaN()
394
395A shortcut to return Math::BigInt->bnan(). Usefull because Perl does not always
396handle bareword C<NaN> properly.
397
398=item upgrade()
399
400Return the class that numbers are upgraded to, is in fact returning
401C<$Math::BigInt::upgrade>.
402
403=back
404
405=head2 MATH LIBRARY
406
407Math with the numbers is done (by default) by a module called
408Math::BigInt::Calc. This is equivalent to saying:
409
410 use bignum lib => 'Calc';
411
412You can change this by using:
413
414 use bignum lib => 'BitVect';
415
416The following would first try to find Math::BigInt::Foo, then
417Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
418
419 use bignum lib => 'Foo,Math::BigInt::Bar';
420
421Please see respective module documentation for further details.
422
423=head2 INTERNAL FORMAT
424
425The numbers are stored as objects, and their internals might change at anytime,
426especially between math operations. The objects also might belong to different
427classes, like Math::BigInt, or Math::BigFLoat. Mixing them together, even
428with normal scalars is not extraordinary, but normal and expected.
429
430You should not depend on the internal format, all accesses must go through
431accessor methods. E.g. looking at $x->{sign} is not a bright idea since there
432is no guaranty that the object in question has such a hashkey, nor is a hash
433underneath at all.
434
435=head2 SIGN
436
437The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
438You can access it with the sign() method.
439
440A sign of 'NaN' is used to represent the result when input arguments are not
441numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
442minus infinity. You will get '+inf' when dividing a positive number by 0, and
443'-inf' when dividing any negative number by 0.
444
445=head1 MODULES USED
446
447C<bignum> is just a thin wrapper around various modules of the Math::BigInt
448family. Think of it as the head of the family, who runs the shop, and orders
449the others to do the work.
450
451The following modules are currently used by bignum:
452
453 Math::BigInt::Lite (for speed, and only if it is loadable)
454 Math::BigInt
455 Math::BigFloat
456
457=head1 EXAMPLES
458
459Some cool command line examples to impress the Python crowd ;)
460
461 perl -Mbignum -le 'print sqrt(33)'
462 perl -Mbignum -le 'print 2*255'
463 perl -Mbignum -le 'print 4.5+2*255'
464 perl -Mbignum -le 'print 3/7 + 5/7 + 8/3'
465 perl -Mbignum -le 'print 123->is_odd()'
466 perl -Mbignum -le 'print log(2)'
467 perl -Mbignum -le 'print 2 ** 0.5'
468 perl -Mbignum=a,65 -le 'print 2 ** 0.2'
469
470=head1 LICENSE
471
472This program is free software; you may redistribute it and/or modify it under
473the same terms as Perl itself.
474
475=head1 SEE ALSO
476
477Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'>.
478
479L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
480as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
481
482=head1 AUTHORS
483
484(C) by Tels L<http://bloodgate.com/> in early 2002, 2003.
485
486=cut
Note: See TracBrowser for help on using the repository browser.