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