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