X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fbignum.pm;h=79fb685c0b68b8027a1c181e31bb55e7c9a6d4af;hb=05bab18efbb4de63339671e0a2623b4e3e26cb88;hp=a9fd9f069770c548e9bfe4b2d868ea0c3c1a1b2f;hpb=504ddc9654486557b94ec8022896e0f68f943bad;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/bignum.pm b/lib/bignum.pm index a9fd9f0..79fb685 100644 --- a/lib/bignum.pm +++ b/lib/bignum.pm @@ -1,10 +1,11 @@ package bignum; require 5.005; -$VERSION = '0.10'; +$VERSION = '0.17'; use Exporter; -@ISA = qw( Exporter ); -@EXPORT_OK = qw( ); +@EXPORT_OK = qw( ); +@EXPORT = qw( inf NaN ); +@ISA = qw( Exporter ); use strict; @@ -32,7 +33,7 @@ sub AUTOLOAD if (defined $_[0]) { Math::BigInt->$name($_[0]); - Math::BigFloat->$name($_[0]); + return Math::BigFloat->$name($_[0]); } return Math::BigInt->$name(); }; @@ -62,7 +63,7 @@ sub import my $self = shift; # some defaults - my $lib = 'Calc'; + my $lib = ''; my $upgrade = 'Math::BigFloat'; my $downgrade = 'Math::BigInt'; @@ -123,7 +124,6 @@ sub import { require Math::BigInt::Trace; $class = 'Math::BigInt::Trace'; $upgrade = 'Math::BigFloat::Trace'; -# print STDERR "Loading $class"; } else { @@ -140,15 +140,15 @@ sub import } require Math::BigInt if $_lite == 0; # not already loaded? $class = 'Math::BigInt'; # regardless of MBIL or not - } + } + push @import, 'lib' => $lib if $lib ne ''; # Math::BigInt::Trace or plain Math::BigInt - $class->import(@import, upgrade => $upgrade, lib => $lib); + $class->import(@import, upgrade => $upgrade); if ($trace) { require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace'; $downgrade = 'Math::BigInt::Trace'; -# print STDERR "Loading $class"; } else { @@ -168,8 +168,12 @@ sub import print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n"; exit; } + $self->export_to_level(1,$self,@a); # export inf and NaN } +sub inf () { Math::BigInt->binf(); } +sub NaN () { Math::BigInt->bnan(); } + 1; __END__ @@ -183,7 +187,9 @@ bignum - Transparent BigNumber support for Perl use bignum; $x = 2 + 4.5,"\n"; # BigFloat 6.5 - print 2 ** 512 * 0.1; # really is what you think it is + print 2 ** 512 * 0.1,"\n"; # really is what you think it is + print inf * inf,"\n"; # prints inf + print NaN * 3,"\n"; # prints NaN =head1 DESCRIPTION @@ -191,7 +197,102 @@ All operators (including basic math operations) are overloaded. Integer and floating-point constants are created as proper BigInts or BigFloats, respectively. -=head2 OPTIONS +If you do + + use bignum; + +at the top of your script, Math::BigFloat and Math::BigInt will be loaded +and any constant number will be converted to an object (Math::BigFloat for +floats like 3.1415 and Math::BigInt for integers like 1234). + +So, the following line: + + $x = 1234; + +creates actually a Math::BigInt and stores a reference to in $x. +This happens transparently and behind your back, so to speak. + +You can see this with the following: + + perl -Mbignum -le 'print ref(1234)' + +Don't worry if it says Math::BigInt::Lite, bignum and friends will use Lite +if it is installed since it is faster for some operations. It will be +automatically upgraded to BigInt whenever necessary: + + perl -Mbignum -le 'print ref(2**255)' + +This also means it is a bad idea to check for some specific package, since +the actual contents of $x might be something unexpected. Due to the +transparent way of bignum C should not be necessary, anyway. + +Since Math::BigInt and BigFloat also overload the normal math operations, +the following line will still work: + + perl -Mbignum -le 'print ref(1234+1234)' + +Since numbers are actually objects, you can call all the usual methods from +BigInt/BigFloat on them. This even works to some extent on expressions: + + perl -Mbignum -le '$x = 1234; print $x->bdec()' + perl -Mbignum -le 'print 1234->binc();' + perl -Mbignum -le 'print 1234->binc->badd(6);' + perl -Mbignum -le 'print +(1234)->binc()' + +(Note that print doesn't do what you expect if the expression starts with +'(' hence the C<+>) + +You can even chain the operations together as usual: + + perl -Mbignum -le 'print 1234->binc->badd(6);' + 1241 + +Under bignum (or bigint or bigrat), Perl will "upgrade" the numbers +appropriately. This means that: + + perl -Mbignum -le 'print 1234+4.5' + 1238.5 + +will work correctly. These mixed cases don't do always work when using +Math::BigInt or Math::BigFloat alone, or at least not in the way normal Perl +scalars work. + +If you do want to work with large integers like under C, try +C: + + perl -Mbigint -le 'print 1234.5+4.5' + 1238 + +There is also C which gives you big rationals: + + perl -Mbigrat -le 'print 1234+4.1' + 12381/10 + +The entire upgrading/downgrading is still experimental and might not work +as you expect or may even have bugs. + +You might get errors like this: + + Can't use an undefined value as an ARRAY reference at + /usr/local/lib/perl5/5.8.0/Math/BigInt/Calc.pm line 864 + +This means somewhere a routine got a BigFloat/Lite but expected a BigInt (or +vice versa) and the upgrade/downgrad path was missing. This is a bug, please +report it so that we can fix it. + +You might consider using just Math::BigInt or Math::BigFloat, since they +allow you finer control over what get's done in which module/space. For +instance, simple loop counters will be Math::BigInts under C and +this is slower than keeping them as Perl scalars: + + perl -Mbignum -le 'for ($i = 0; $i < 10; $i++) { print ref($i); }' + +Please note the following does not work as expected (prints nothing), since +overloading of '..' is not yet possible in Perl (as of v5.8.0): + + perl -Mbignum -le 'for (1..2) { print ref($_); }' + +=head2 Options bignum recognizes some options that can be passed while loading it via use. The options can (currently) be either a single letter form, or the long form. @@ -233,7 +334,73 @@ line. This will be hopefully fixed soon ;) This prints out the name and version of all modules used and then exits. - perl -Mbignum=v -e '' + perl -Mbignum=v + +=head2 Methods + +Beside import() and AUTOLOAD() there are only a few other methods. + +Since all numbers are now objects, you can use all functions that are part of +the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not +the fxxx() notation, though. This makes it possible that the underlying object +might morph into a different class than BigFloat. + +=head2 Caveat + +But a warning is in order. When using the following to make a copy of a number, +only a shallow copy will be made. + + $x = 9; $y = $x; + $x = $y = 7; + +If you want to make a real copy, use the following: + + $y = $x->copy(); + +Using the copy or the original with overloaded math is okay, e.g. the +following work: + + $x = 9; $y = $x; + print $x + 1, " ", $y,"\n"; # prints 10 9 + +but calling any method that modifies the number directly will result in +B the original and the copy being destroyed: + + $x = 9; $y = $x; + print $x->badd(1), " ", $y,"\n"; # prints 10 10 + + $x = 9; $y = $x; + print $x->binc(1), " ", $y,"\n"; # prints 10 10 + + $x = 9; $y = $x; + print $x->bmul(2), " ", $y,"\n"; # prints 18 18 + +Using methods that do not modify, but testthe contents works: + + $x = 9; $y = $x; + $z = 9 if $x->is_zero(); # works fine + +See the documentation about the copy constructor and C<=> in overload, as +well as the documentation in BigInt for further details. + +=over 2 + +=item inf() + +A shortcut to return Math::BigInt->binf(). Useful because Perl does not always +handle bareword C properly. + +=item NaN() + +A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always +handle bareword C properly. + +=item upgrade() + +Return the class that numbers are upgraded to, is in fact returning +C<$Math::BigInt::upgrade>. + +=back =head2 MATH LIBRARY @@ -275,13 +442,6 @@ numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively minus infinity. You will get '+inf' when dividing a positive number by 0, and '-inf' when dividing any negative number by 0. -=head2 METHODS - -Since all numbers are now objects, you can use all functions that are part of -the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not -the fxxx() notation, though. This makes it possible that the underlying object -might morph into a different class than BigFloat. - =head1 MODULES USED C is just a thin wrapper around various modules of the Math::BigInt @@ -321,6 +481,6 @@ as L, L and L. =head1 AUTHORS -(C) by Tels L in early 2002. +(C) by Tels L in early 2002, 2003. =cut