1package bigrat; 2 3use 5.010; 4use strict; 5use warnings; 6 7our $VERSION = '0.49'; 8 9use Exporter; 10our @ISA = qw( bigint ); 11our @EXPORT_OK = qw( PI e bpi bexp hex oct ); 12our @EXPORT = qw( inf NaN ); 13 14use overload; 15use bigint (); 16 17############################################################################## 18 19BEGIN { 20 *inf = \&bigint::inf; 21 *NaN = \&bigint::NaN; 22 *hex = \&bigint::hex; 23 *oct = \&bigint::oct; 24} 25 26# These are all alike, and thus faked by AUTOLOAD 27 28my @faked = qw/round_mode accuracy precision div_scale/; 29our ($AUTOLOAD, $_lite); # _lite for testsuite 30 31sub AUTOLOAD { 32 my $name = $AUTOLOAD; 33 34 $name =~ s/.*:://; # split package 35 no strict 'refs'; 36 foreach my $n (@faked) { 37 if ($n eq $name) { 38 *{"bigrat::$name"} = 39 sub { 40 my $self = shift; 41 no strict 'refs'; 42 if (defined $_[0]) { 43 Math::BigInt->$name($_[0]); 44 Math::BigFloat->$name($_[0]); 45 return Math::BigRat->$name($_[0]); 46 } 47 return Math::BigInt->$name(); 48 }; 49 return &$name; 50 } 51 } 52 53 # delayed load of Carp and avoid recursion 54 require Carp; 55 Carp::croak ("Can't call bigrat\-\>$name, not a valid method"); 56} 57 58sub unimport { 59 $^H{bigrat} = undef; # no longer in effect 60 overload::remove_constant('binary', '', 'float', '', 'integer'); 61} 62 63sub in_effect { 64 my $level = shift || 0; 65 my $hinthash = (caller($level))[10]; 66 $hinthash->{bigrat}; 67} 68 69############################################################################# 70 71sub import { 72 my $self = shift; 73 74 # see also bignum->import() for additional comments 75 76 $^H{bigrat} = 1; # we are in effect 77 78 # for newer Perls always override hex() and oct() with a lexical version: 79 if ($] > 5.009004) { 80 bigint::_override(); 81 } 82 # some defaults 83 my $lib = ''; 84 my $lib_kind = 'try'; 85 my $upgrade = 'Math::BigFloat'; 86 87 my @import = (':constant'); # drive it w/ constant 88 my @a = @_; 89 my $l = scalar @_; 90 my $j = 0; 91 my ($a, $p); 92 my ($ver, $trace); # version? trace? 93 for (my $i = 0; $i < $l ; $i++, $j++) { 94 if ($_[$i] eq 'upgrade') { 95 # this causes upgrading 96 $upgrade = $_[$i + 1]; # or undef to disable 97 my $s = 2; 98 $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..." 99 splice @a, $j, $s; 100 $j -= $s; 101 } 102 elsif ($_[$i] =~ /^(l|lib|try|only)$/) { 103 # this causes a different low lib to take care... 104 $lib_kind = $1; 105 $lib_kind = 'lib' if $lib_kind eq 'l'; 106 $lib = $_[$i + 1] || ''; 107 my $s = 2; 108 $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..." 109 splice @a, $j, $s; 110 $j -= $s; 111 $i++; 112 } 113 elsif ($_[$i] =~ /^(a|accuracy)$/) { 114 $a = $_[$i + 1]; 115 my $s = 2; 116 $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..." 117 splice @a, $j, $s; 118 $j -= $s; 119 $i++; 120 } 121 elsif ($_[$i] =~ /^(p|precision)$/) { 122 $p = $_[$i + 1]; 123 my $s = 2; 124 $s = 1 if @a - $j < 2; # avoid "can not modify non-existent..." 125 splice @a, $j, $s; 126 $j -= $s; 127 $i++; 128 } 129 elsif ($_[$i] =~ /^(v|version)$/) { 130 $ver = 1; 131 splice @a, $j, 1; 132 $j--; 133 } 134 elsif ($_[$i] =~ /^(t|trace)$/) { 135 $trace = 1; 136 splice @a, $j, 1; 137 $j--; 138 } 139 elsif ($_[$i] !~ /^(PI|e|bpi|bexp|hex|oct)\z/) { 140 die ("unknown option $_[$i]"); 141 } 142 } 143 my $class; 144 $_lite = 0; # using M::BI::L ? 145 if ($trace) { 146 require Math::BigInt::Trace; 147 $class = 'Math::BigInt::Trace'; 148 $upgrade = 'Math::BigFloat::Trace'; 149 } 150 else { 151 # see if we can find Math::BigInt::Lite 152 if (!defined $a && !defined $p) { # rounding won't work to well 153 local @INC = @INC; 154 pop @INC if $INC[-1] eq '.'; 155 if (eval { require Math::BigInt::Lite; 1 }) { 156 @import = (); # :constant in Lite, not MBI 157 Math::BigInt::Lite->import(':constant'); 158 $_lite = 1; # signal okay 159 } 160 } 161 require Math::BigInt if $_lite == 0; # not already loaded? 162 $class = 'Math::BigInt'; # regardless of MBIL or not 163 } 164 push @import, $lib_kind => $lib if $lib ne ''; 165 # Math::BigInt::Trace or plain Math::BigInt 166 $class->import(@import, upgrade => $upgrade); 167 168 require Math::BigFloat; 169 Math::BigFloat->import(upgrade => 'Math::BigRat', ':constant'); 170 require Math::BigRat; 171 Math::BigRat->import(@import); 172 173 bigrat->accuracy($a) if defined $a; 174 bigrat->precision($p) if defined $p; 175 if ($ver) { 176 print "bigrat\t\t\t v$VERSION\n"; 177 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite; 178 print "Math::BigInt\t\t v$Math::BigInt::VERSION"; 179 my $config = Math::BigInt->config(); 180 print " lib => $config->{lib} v$config->{lib_version}\n"; 181 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n"; 182 print "Math::BigRat\t\t v$Math::BigRat::VERSION\n"; 183 exit; 184 } 185 186 # Take care of octal/hexadecimal constants 187 overload::constant binary => 188 sub { 189 bigint::_binary_constant(shift); 190 }; 191 192 # if another big* was already loaded: 193 my ($package) = caller(); 194 195 no strict 'refs'; 196 if (!defined *{"${package}::inf"}) { 197 $self->export_to_level(1, $self, @a); # export inf and NaN 198 } 199} 200 201sub PI () { Math::BigFloat->new('3.141592653589793238462643383279502884197'); } 202sub e () { Math::BigFloat->new('2.718281828459045235360287471352662497757'); } 203 204sub bpi ($) { 205 local $Math::BigFloat::upgrade; 206 Math::BigFloat->bpi(@_); 207} 208 209sub bexp ($$) { 210 local $Math::BigFloat::upgrade; 211 my $x = Math::BigFloat->new($_[0]); 212 $x->bexp($_[1]); 213} 214 2151; 216 217__END__ 218 219=pod 220 221=head1 NAME 222 223bigrat - Transparent BigNumber/BigRational support for Perl 224 225=head1 SYNOPSIS 226 227 use bigrat; 228 229 print 2 + 4.5,"\n"; # BigFloat 6.5 230 print 1/3 + 1/4,"\n"; # produces 7/12 231 232 { 233 no bigrat; 234 print 1/3,"\n"; # 0.33333... 235 } 236 237 # Import into current package: 238 use bigrat qw/hex oct/; 239 print hex("0x1234567890123490"),"\n"; 240 print oct("01234567890123490"),"\n"; 241 242=head1 DESCRIPTION 243 244All operators (including basic math operations) are overloaded. Integer and 245floating-point constants are created as proper BigInts or BigFloats, 246respectively. 247 248Other than L<bignum>, this module upgrades to Math::BigRat, meaning that 249instead of 2.5 you will get 2+1/2 as output. 250 251=head2 Modules Used 252 253C<bigrat> is just a thin wrapper around various modules of the Math::BigInt 254family. Think of it as the head of the family, who runs the shop, and orders 255the others to do the work. 256 257The following modules are currently used by bignum: 258 259 Math::BigInt::Lite (for speed, and only if it is loadable) 260 Math::BigInt 261 Math::BigFloat 262 Math::BigRat 263 264=head2 Math Library 265 266Math with the numbers is done (by default) by a module called 267Math::BigInt::Calc. This is equivalent to saying: 268 269 use bigrat lib => 'Calc'; 270 271You can change this by using: 272 273 use bignum lib => 'GMP'; 274 275The following would first try to find Math::BigInt::Foo, then 276Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc: 277 278 use bigrat lib => 'Foo,Math::BigInt::Bar'; 279 280Using C<lib> warns if none of the specified libraries can be found and 281L<Math::BigInt> did fall back to one of the default libraries. 282To suppress this warning, use C<try> instead: 283 284 use bignum try => 'GMP'; 285 286If you want the code to die instead of falling back, use C<only> instead: 287 288 use bignum only => 'GMP'; 289 290Please see respective module documentation for further details. 291 292=head2 Sign 293 294The sign is either '+', '-', 'NaN', '+inf' or '-inf'. 295 296A sign of 'NaN' is used to represent the result when input arguments are not 297numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively 298minus infinity. You will get '+inf' when dividing a positive number by 0, and 299'-inf' when dividing any negative number by 0. 300 301=head2 Methods 302 303Since all numbers are not objects, you can use all functions that are part of 304the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not 305the fxxx() notation, though. This makes you independent on the fact that the 306underlying object might morph into a different class than BigFloat. 307 308=over 2 309 310=item inf() 311 312A shortcut to return Math::BigInt->binf(). Useful because Perl does not always 313handle bareword C<inf> properly. 314 315=item NaN() 316 317A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always 318handle bareword C<NaN> properly. 319 320=item e 321 322 # perl -Mbigrat=e -wle 'print e' 323 324Returns Euler's number C<e>, aka exp(1). 325 326=item PI 327 328 # perl -Mbigrat=PI -wle 'print PI' 329 330Returns PI. 331 332=item bexp() 333 334 bexp($power,$accuracy); 335 336Returns Euler's number C<e> raised to the appropriate power, to 337the wanted accuracy. 338 339Example: 340 341 # perl -Mbigrat=bexp -wle 'print bexp(1,80)' 342 343=item bpi() 344 345 bpi($accuracy); 346 347Returns PI to the wanted accuracy. 348 349Example: 350 351 # perl -Mbigrat=bpi -wle 'print bpi(80)' 352 353=item upgrade() 354 355Return the class that numbers are upgraded to, is in fact returning 356C<$Math::BigInt::upgrade>. 357 358=item in_effect() 359 360 use bigrat; 361 362 print "in effect\n" if bigrat::in_effect; # true 363 { 364 no bigrat; 365 print "in effect\n" if bigrat::in_effect; # false 366 } 367 368Returns true or false if C<bigrat> is in effect in the current scope. 369 370This method only works on Perl v5.9.4 or later. 371 372=back 373 374=head2 MATH LIBRARY 375 376Math with the numbers is done (by default) by a module called 377 378=head2 Caveat 379 380But a warning is in order. When using the following to make a copy of a number, 381only a shallow copy will be made. 382 383 $x = 9; $y = $x; 384 $x = $y = 7; 385 386If you want to make a real copy, use the following: 387 388 $y = $x->copy(); 389 390Using the copy or the original with overloaded math is okay, e.g. the 391following work: 392 393 $x = 9; $y = $x; 394 print $x + 1, " ", $y,"\n"; # prints 10 9 395 396but calling any method that modifies the number directly will result in 397B<both> the original and the copy being destroyed: 398 399 $x = 9; $y = $x; 400 print $x->badd(1), " ", $y,"\n"; # prints 10 10 401 402 $x = 9; $y = $x; 403 print $x->binc(1), " ", $y,"\n"; # prints 10 10 404 405 $x = 9; $y = $x; 406 print $x->bmul(2), " ", $y,"\n"; # prints 18 18 407 408Using methods that do not modify, but testthe contents works: 409 410 $x = 9; $y = $x; 411 $z = 9 if $x->is_zero(); # works fine 412 413See the documentation about the copy constructor and C<=> in overload, as 414well as the documentation in BigInt for further details. 415 416=head2 Options 417 418bignum recognizes some options that can be passed while loading it via use. 419The options can (currently) be either a single letter form, or the long form. 420The following options exist: 421 422=over 2 423 424=item a or accuracy 425 426This sets the accuracy for all math operations. The argument must be greater 427than or equal to zero. See Math::BigInt's bround() function for details. 428 429 perl -Mbigrat=a,50 -le 'print sqrt(20)' 430 431Note that setting precision and accuracy at the same time is not possible. 432 433=item p or precision 434 435This sets the precision for all math operations. The argument can be any 436integer. Negative values mean a fixed number of digits after the dot, while 437a positive value rounds to this digit left from the dot. 0 or 1 mean round to 438integer. See Math::BigInt's bfround() function for details. 439 440 perl -Mbigrat=p,-50 -le 'print sqrt(20)' 441 442Note that setting precision and accuracy at the same time is not possible. 443 444=item t or trace 445 446This enables a trace mode and is primarily for debugging bignum or 447Math::BigInt/Math::BigFloat. 448 449=item l or lib 450 451Load a different math lib, see L<MATH LIBRARY>. 452 453 perl -Mbigrat=l,GMP -e 'print 2 ** 512' 454 455Currently there is no way to specify more than one library on the command 456line. This means the following does not work: 457 458 perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512' 459 460This will be hopefully fixed soon ;) 461 462=item hex 463 464Override the built-in hex() method with a version that can handle big 465numbers. This overrides it by exporting it to the current package. Under 466Perl v5.10.0 and higher, this is not so necessary, as hex() is lexically 467overridden in the current scope whenever the bigrat pragma is active. 468 469=item oct 470 471Override the built-in oct() method with a version that can handle big 472numbers. This overrides it by exporting it to the current package. Under 473Perl v5.10.0 and higher, this is not so necessary, as oct() is lexically 474overridden in the current scope whenever the bigrat pragma is active. 475 476=item v or version 477 478This prints out the name and version of all modules used and then exits. 479 480 perl -Mbigrat=v 481 482=back 483 484=head1 CAVEATS 485 486=over 2 487 488=item Operator vs literal overloading 489 490C<bigrat> works by overloading handling of integer and floating point 491literals, converting them to L<Math::BigInt> or L<Math::BigRat> 492objects. 493 494This means that arithmetic involving only string values or string 495literals will be performed using Perl's built-in operators. 496 497For example: 498 499 use bigrat; 500 my $x = "900000000000000009"; 501 my $y = "900000000000000007"; 502 print $x - $y; 503 504will output C<0> on default 32-bit builds, since C<bigrat> never sees 505the string literals. To ensure the expression is all treated as 506C<Math::BigInt> or C<Math::BigRat> objects, use a literal number in 507the expression: 508 509 print +(0+$x) - $y; 510 511=item in_effect() 512 513This method only works on Perl v5.9.4 or later. 514 515=item hex()/oct() 516 517C<bigint> overrides these routines with versions that can also handle 518big integer values. Under Perl prior to version v5.9.4, however, this 519will not happen unless you specifically ask for it with the two 520import tags "hex" and "oct" - and then it will be global and cannot be 521disabled inside a scope with "no bigint": 522 523 use bigint qw/hex oct/; 524 525 print hex("0x1234567890123456"); 526 { 527 no bigint; 528 print hex("0x1234567890123456"); 529 } 530 531The second call to hex() will warn about a non-portable constant. 532 533Compare this to: 534 535 use bigint; 536 537 # will warn only under Perl older than v5.9.4 538 print hex("0x1234567890123456"); 539 540=back 541 542=head1 EXAMPLES 543 544 perl -Mbigrat -le 'print sqrt(33)' 545 perl -Mbigrat -le 'print 2*255' 546 perl -Mbigrat -le 'print 4.5+2*255' 547 perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3' 548 perl -Mbigrat -le 'print 12->is_odd()'; 549 perl -Mbignum=l,GMP -le 'print 7 ** 7777' 550 551=head1 BUGS 552 553For information about bugs and how to report them, see the BUGS section in the 554documentation available with the perldoc command. 555 556 perldoc bignum 557 558=head1 SUPPORT 559 560You can find documentation for this module with the perldoc command. 561 562 perldoc bigrat 563 564For more information, see the SUPPORT section in the documentation available 565with the perldoc command. 566 567 perldoc bignum 568 569=head1 LICENSE 570 571This program is free software; you may redistribute it and/or modify it under 572the same terms as Perl itself. 573 574=head1 SEE ALSO 575 576L<bignum> and L<bigint>. 577 578L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigRat> and L<Math::Big> as well as 579L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>. 580 581=head1 AUTHORS 582 583=over 4 584 585=item * 586 587(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007. 588 589=item * 590 591Peter John Acklam E<lt>pjacklam@gmail.com<gt>, 2014-. 592 593=back 594 595=cut 596