1b8851fccSafresh1package bigrat; 2b8851fccSafresh1 3b8851fccSafresh1use strict; 4b8851fccSafresh1use warnings; 5b8851fccSafresh1 6eac174f2Safresh1use Carp qw< carp croak >; 7eac174f2Safresh1 8*3d61058aSafresh1our $VERSION = '0.67'; 9b8851fccSafresh1 10b8851fccSafresh1use Exporter; 11eac174f2Safresh1our @ISA = qw( Exporter ); 12b8851fccSafresh1our @EXPORT_OK = qw( PI e bpi bexp hex oct ); 13b8851fccSafresh1our @EXPORT = qw( inf NaN ); 14b8851fccSafresh1 15b8851fccSafresh1use overload; 16eac174f2Safresh1 17eac174f2Safresh1my $obj_class = "Math::BigRat"; 18b8851fccSafresh1 19b8851fccSafresh1############################################################################## 20b8851fccSafresh1 21eac174f2Safresh1sub accuracy { 22b8851fccSafresh1 my $self = shift; 23eac174f2Safresh1 $obj_class -> accuracy(@_); 24b8851fccSafresh1} 25b8851fccSafresh1 26eac174f2Safresh1sub precision { 27eac174f2Safresh1 my $self = shift; 28eac174f2Safresh1 $obj_class -> precision(@_); 29b8851fccSafresh1} 30b8851fccSafresh1 31eac174f2Safresh1sub round_mode { 32eac174f2Safresh1 my $self = shift; 33eac174f2Safresh1 $obj_class -> round_mode(@_); 34eac174f2Safresh1} 35eac174f2Safresh1 36eac174f2Safresh1sub div_scale { 37eac174f2Safresh1 my $self = shift; 38eac174f2Safresh1 $obj_class -> div_scale(@_); 39b8851fccSafresh1} 40b8851fccSafresh1 41b8851fccSafresh1sub in_effect { 42b8851fccSafresh1 my $level = shift || 0; 43b8851fccSafresh1 my $hinthash = (caller($level))[10]; 44b8851fccSafresh1 $hinthash->{bigrat}; 45b8851fccSafresh1} 46b8851fccSafresh1 47eac174f2Safresh1sub _float_constant { 48eac174f2Safresh1 my $str = shift; 49eac174f2Safresh1 50eac174f2Safresh1 # See if we can convert the input string to a string using a normalized form 51eac174f2Safresh1 # consisting of the significand as a signed integer, the character "e", and 52eac174f2Safresh1 # the exponent as a signed integer, e.g., "+0e+0", "+314e-2", and "-1e+3". 53eac174f2Safresh1 54eac174f2Safresh1 my $nstr; 55eac174f2Safresh1 56eac174f2Safresh1 if ( 57eac174f2Safresh1 # See if it is an octal number. An octal number like '0377' is also 58eac174f2Safresh1 # accepted by the functions parsing decimal and hexadecimal numbers, so 59eac174f2Safresh1 # handle octal numbers before decimal and hexadecimal numbers. 60eac174f2Safresh1 61eac174f2Safresh1 $str =~ /^0(?:[Oo]|_*[0-7])/ and 62eac174f2Safresh1 $nstr = Math::BigInt -> oct_str_to_dec_flt_str($str) 63eac174f2Safresh1 64eac174f2Safresh1 or 65eac174f2Safresh1 66eac174f2Safresh1 # See if it is decimal number. 67eac174f2Safresh1 68eac174f2Safresh1 $nstr = Math::BigInt -> dec_str_to_dec_flt_str($str) 69eac174f2Safresh1 70eac174f2Safresh1 or 71eac174f2Safresh1 72eac174f2Safresh1 # See if it is a hexadecimal number. Every hexadecimal number has a 73eac174f2Safresh1 # prefix, but the functions parsing numbers don't require it, so check 74eac174f2Safresh1 # to see if it actually is a hexadecimal number. 75eac174f2Safresh1 76eac174f2Safresh1 $str =~ /^0[Xx]/ and 77eac174f2Safresh1 $nstr = Math::BigInt -> hex_str_to_dec_flt_str($str) 78eac174f2Safresh1 79eac174f2Safresh1 or 80eac174f2Safresh1 81eac174f2Safresh1 # See if it is a binary numbers. Every binary number has a prefix, but 82eac174f2Safresh1 # the functions parsing numbers don't require it, so check to see if it 83eac174f2Safresh1 # actually is a binary number. 84eac174f2Safresh1 85eac174f2Safresh1 $str =~ /^0[Bb]/ and 86eac174f2Safresh1 $nstr = Math::BigInt -> bin_str_to_dec_flt_str($str)) 87eac174f2Safresh1 { 88eac174f2Safresh1 return $obj_class -> new($nstr); 89eac174f2Safresh1 } 90eac174f2Safresh1 91eac174f2Safresh1 # If we get here, there is a bug in the code above this point. 92eac174f2Safresh1 93eac174f2Safresh1 warn "Internal error: unable to handle literal constant '$str'.", 94eac174f2Safresh1 " This is a bug, so please report this to the module author."; 95eac174f2Safresh1 return $obj_class -> bnan(); 96eac174f2Safresh1} 97eac174f2Safresh1 98b8851fccSafresh1############################################################################# 99eac174f2Safresh1# the following two routines are for "use bigrat qw/hex oct/;": 100eac174f2Safresh1 101eac174f2Safresh1use constant LEXICAL => $] > 5.009004; 102eac174f2Safresh1 103eac174f2Safresh1# Internal function with the same semantics as CORE::hex(). This function is 104eac174f2Safresh1# not used directly, but rather by other front-end functions. 105eac174f2Safresh1 106eac174f2Safresh1sub _hex_core { 107eac174f2Safresh1 my $str = shift; 108eac174f2Safresh1 109eac174f2Safresh1 # Strip off, clean, and parse as much as we can from the beginning. 110eac174f2Safresh1 111eac174f2Safresh1 my $x; 112eac174f2Safresh1 if ($str =~ s/ ^ ( 0? [xX] )? ( [0-9a-fA-F]* ( _ [0-9a-fA-F]+ )* ) //x) { 113eac174f2Safresh1 my $chrs = $2; 114eac174f2Safresh1 $chrs =~ tr/_//d; 115eac174f2Safresh1 $chrs = '0' unless CORE::length $chrs; 116eac174f2Safresh1 $x = $obj_class -> from_hex($chrs); 117eac174f2Safresh1 } else { 118eac174f2Safresh1 $x = $obj_class -> bzero(); 119eac174f2Safresh1 } 120eac174f2Safresh1 121eac174f2Safresh1 # Warn about trailing garbage. 122eac174f2Safresh1 123eac174f2Safresh1 if (CORE::length($str)) { 124eac174f2Safresh1 require Carp; 125eac174f2Safresh1 Carp::carp(sprintf("Illegal hexadecimal digit '%s' ignored", 126eac174f2Safresh1 substr($str, 0, 1))); 127eac174f2Safresh1 } 128eac174f2Safresh1 129eac174f2Safresh1 return $x; 130eac174f2Safresh1} 131eac174f2Safresh1 132eac174f2Safresh1# Internal function with the same semantics as CORE::oct(). This function is 133eac174f2Safresh1# not used directly, but rather by other front-end functions. 134eac174f2Safresh1 135eac174f2Safresh1sub _oct_core { 136eac174f2Safresh1 my $str = shift; 137eac174f2Safresh1 138eac174f2Safresh1 $str =~ s/^\s*//; 139eac174f2Safresh1 140eac174f2Safresh1 # Hexadecimal input. 141eac174f2Safresh1 142eac174f2Safresh1 return _hex_core($str) if $str =~ /^0?[xX]/; 143eac174f2Safresh1 144eac174f2Safresh1 my $x; 145eac174f2Safresh1 146eac174f2Safresh1 # Binary input. 147eac174f2Safresh1 148eac174f2Safresh1 if ($str =~ /^0?[bB]/) { 149eac174f2Safresh1 150eac174f2Safresh1 # Strip off, clean, and parse as much as we can from the beginning. 151eac174f2Safresh1 152eac174f2Safresh1 if ($str =~ s/ ^ ( 0? [bB] )? ( [01]* ( _ [01]+ )* ) //x) { 153eac174f2Safresh1 my $chrs = $2; 154eac174f2Safresh1 $chrs =~ tr/_//d; 155eac174f2Safresh1 $chrs = '0' unless CORE::length $chrs; 156eac174f2Safresh1 $x = $obj_class -> from_bin($chrs); 157eac174f2Safresh1 } 158eac174f2Safresh1 159eac174f2Safresh1 # Warn about trailing garbage. 160eac174f2Safresh1 161eac174f2Safresh1 if (CORE::length($str)) { 162eac174f2Safresh1 require Carp; 163eac174f2Safresh1 Carp::carp(sprintf("Illegal binary digit '%s' ignored", 164eac174f2Safresh1 substr($str, 0, 1))); 165eac174f2Safresh1 } 166eac174f2Safresh1 167eac174f2Safresh1 return $x; 168eac174f2Safresh1 } 169eac174f2Safresh1 170eac174f2Safresh1 # Octal input. Strip off, clean, and parse as much as we can from the 171eac174f2Safresh1 # beginning. 172eac174f2Safresh1 173eac174f2Safresh1 if ($str =~ s/ ^ ( 0? [oO] )? ( [0-7]* ( _ [0-7]+ )* ) //x) { 174eac174f2Safresh1 my $chrs = $2; 175eac174f2Safresh1 $chrs =~ tr/_//d; 176eac174f2Safresh1 $chrs = '0' unless CORE::length $chrs; 177eac174f2Safresh1 $x = $obj_class -> from_oct($chrs); 178eac174f2Safresh1 } 179eac174f2Safresh1 180eac174f2Safresh1 # Warn about trailing garbage. CORE::oct() only warns about 8 and 9, but it 181eac174f2Safresh1 # is more helpful to warn about all invalid digits. 182eac174f2Safresh1 183eac174f2Safresh1 if (CORE::length($str)) { 184eac174f2Safresh1 require Carp; 185eac174f2Safresh1 Carp::carp(sprintf("Illegal octal digit '%s' ignored", 186eac174f2Safresh1 substr($str, 0, 1))); 187eac174f2Safresh1 } 188eac174f2Safresh1 189eac174f2Safresh1 return $x; 190eac174f2Safresh1} 191eac174f2Safresh1 192eac174f2Safresh1{ 193eac174f2Safresh1 my $proto = LEXICAL ? '_' : ';$'; 194eac174f2Safresh1 eval ' 195eac174f2Safresh1sub hex(' . $proto . ') {' . <<'.'; 196eac174f2Safresh1 my $str = @_ ? $_[0] : $_; 197eac174f2Safresh1 _hex_core($str); 198eac174f2Safresh1} 199eac174f2Safresh1. 200eac174f2Safresh1 201eac174f2Safresh1 eval ' 202eac174f2Safresh1sub oct(' . $proto . ') {' . <<'.'; 203eac174f2Safresh1 my $str = @_ ? $_[0] : $_; 204eac174f2Safresh1 _oct_core($str); 205eac174f2Safresh1} 206eac174f2Safresh1. 207eac174f2Safresh1} 208eac174f2Safresh1 209eac174f2Safresh1############################################################################# 210eac174f2Safresh1# the following two routines are for Perl 5.9.4 or later and are lexical 211eac174f2Safresh1 212eac174f2Safresh1my ($prev_oct, $prev_hex, $overridden); 213eac174f2Safresh1 214eac174f2Safresh1if (LEXICAL) { eval <<'.' } 215eac174f2Safresh1sub _hex(_) { 216eac174f2Safresh1 my $hh = (caller 0)[10]; 217eac174f2Safresh1 return $$hh{bigrat} ? bigrat::_hex_core($_[0]) 218eac174f2Safresh1 : $$hh{bigfloat} ? bigfloat::_hex_core($_[0]) 219eac174f2Safresh1 : $$hh{bigint} ? bigint::_hex_core($_[0]) 220eac174f2Safresh1 : $prev_hex ? &$prev_hex($_[0]) 221eac174f2Safresh1 : CORE::hex($_[0]); 222eac174f2Safresh1} 223eac174f2Safresh1 224eac174f2Safresh1sub _oct(_) { 225eac174f2Safresh1 my $hh = (caller 0)[10]; 226eac174f2Safresh1 return $$hh{bigrat} ? bigrat::_oct_core($_[0]) 227eac174f2Safresh1 : $$hh{bigfloat} ? bigfloat::_oct_core($_[0]) 228eac174f2Safresh1 : $$hh{bigint} ? bigint::_oct_core($_[0]) 229eac174f2Safresh1 : $prev_oct ? &$prev_oct($_[0]) 230eac174f2Safresh1 : CORE::oct($_[0]); 231eac174f2Safresh1} 232eac174f2Safresh1. 233eac174f2Safresh1 234eac174f2Safresh1sub _override { 235eac174f2Safresh1 return if $overridden; 236eac174f2Safresh1 $prev_oct = *CORE::GLOBAL::oct{CODE}; 237eac174f2Safresh1 $prev_hex = *CORE::GLOBAL::hex{CODE}; 238eac174f2Safresh1 no warnings 'redefine'; 239eac174f2Safresh1 *CORE::GLOBAL::oct = \&_oct; 240eac174f2Safresh1 *CORE::GLOBAL::hex = \&_hex; 241eac174f2Safresh1 $overridden = 1; 242eac174f2Safresh1} 243eac174f2Safresh1 244eac174f2Safresh1sub unimport { 245*3d61058aSafresh1 delete $^H{bigrat}; # no longer in effect 246eac174f2Safresh1 overload::remove_constant('binary', '', 'float', '', 'integer'); 247eac174f2Safresh1} 248b8851fccSafresh1 249b8851fccSafresh1sub import { 250eac174f2Safresh1 my $class = shift; 251b8851fccSafresh1 252b8851fccSafresh1 $^H{bigrat} = 1; # we are in effect 253*3d61058aSafresh1 delete $^H{bigint}; 254*3d61058aSafresh1 delete $^H{bigfloat}; 255b8851fccSafresh1 256b8851fccSafresh1 # for newer Perls always override hex() and oct() with a lexical version: 257eac174f2Safresh1 if (LEXICAL) { 258eac174f2Safresh1 _override(); 259b8851fccSafresh1 } 260b8851fccSafresh1 261eac174f2Safresh1 my @import = (); 262eac174f2Safresh1 my @a = (); # unrecognized arguments 263eac174f2Safresh1 my $ver; # version? 264eac174f2Safresh1 265eac174f2Safresh1 while (@_) { 266eac174f2Safresh1 my $param = shift; 267eac174f2Safresh1 268eac174f2Safresh1 # Accuracy. 269eac174f2Safresh1 270eac174f2Safresh1 if ($param =~ /^a(ccuracy)?$/) { 271eac174f2Safresh1 push @import, 'accuracy', shift(); 272eac174f2Safresh1 next; 273b8851fccSafresh1 } 274eac174f2Safresh1 275eac174f2Safresh1 # Precision. 276eac174f2Safresh1 277eac174f2Safresh1 if ($param =~ /^p(recision)?$/) { 278eac174f2Safresh1 push @import, 'precision', shift(); 279eac174f2Safresh1 next; 280b8851fccSafresh1 } 281eac174f2Safresh1 282eac174f2Safresh1 # Rounding mode. 283eac174f2Safresh1 284eac174f2Safresh1 if ($param eq 'round_mode') { 285eac174f2Safresh1 push @import, 'round_mode', shift(); 286eac174f2Safresh1 next; 287b8851fccSafresh1 } 288eac174f2Safresh1 289eac174f2Safresh1 # Backend library. 290eac174f2Safresh1 291eac174f2Safresh1 if ($param =~ /^(l|lib|try|only)$/) { 292eac174f2Safresh1 push @import, $param eq 'l' ? 'lib' : $param; 293eac174f2Safresh1 push @import, shift() if @_; 294eac174f2Safresh1 next; 295b8851fccSafresh1 } 296eac174f2Safresh1 297eac174f2Safresh1 if ($param =~ /^(v|version)$/) { 298b8851fccSafresh1 $ver = 1; 299eac174f2Safresh1 next; 300b8851fccSafresh1 } 301b8851fccSafresh1 302eac174f2Safresh1 if ($param =~ /^(t|trace)$/) { 303eac174f2Safresh1 $obj_class .= "::Trace"; 304eac174f2Safresh1 eval "require $obj_class"; 305eac174f2Safresh1 die $@ if $@; 306eac174f2Safresh1 next; 307eac174f2Safresh1 } 308b8851fccSafresh1 309eac174f2Safresh1 if ($param =~ /^(PI|e|bexp|bpi|hex|oct)\z/) { 310eac174f2Safresh1 push @a, $param; 311eac174f2Safresh1 next; 312eac174f2Safresh1 } 313eac174f2Safresh1 314eac174f2Safresh1 croak("Unknown option '$param'"); 315eac174f2Safresh1 } 316eac174f2Safresh1 317eac174f2Safresh1 eval "require $obj_class"; 318eac174f2Safresh1 die $@ if $@; 319eac174f2Safresh1 $obj_class -> import(@import); 320eac174f2Safresh1 321b8851fccSafresh1 if ($ver) { 322eac174f2Safresh1 printf "%-31s v%s\n", $class, $class -> VERSION(); 323eac174f2Safresh1 printf " lib => %-23s v%s\n", 324eac174f2Safresh1 $obj_class -> config("lib"), $obj_class -> config("lib_version"); 325eac174f2Safresh1 printf "%-31s v%s\n", $obj_class, $obj_class -> VERSION(); 326b8851fccSafresh1 exit; 327b8851fccSafresh1 } 328b8851fccSafresh1 329eac174f2Safresh1 $class -> export_to_level(1, $class, @a); # export inf, NaN, etc. 330eac174f2Safresh1 331eac174f2Safresh1 overload::constant 332eac174f2Safresh1 333eac174f2Safresh1 # This takes care each number written as decimal integer and within the 334eac174f2Safresh1 # range of what perl can represent as an integer, e.g., "314", but not 335eac174f2Safresh1 # "3141592653589793238462643383279502884197169399375105820974944592307". 336eac174f2Safresh1 337eac174f2Safresh1 integer => sub { 338eac174f2Safresh1 #printf "Value '%s' handled by the 'integer' sub.\n", $_[0]; 339eac174f2Safresh1 my $str = shift; 340eac174f2Safresh1 return $obj_class -> new($str); 341eac174f2Safresh1 }, 342eac174f2Safresh1 343eac174f2Safresh1 # This takes care of each number written with a decimal point and/or 344eac174f2Safresh1 # using floating point notation, e.g., "3.", "3.0", "3.14e+2" (decimal), 345eac174f2Safresh1 # "0b1.101p+2" (binary), "03.14p+2" and "0o3.14p+2" (octal), and 346eac174f2Safresh1 # "0x3.14p+2" (hexadecimal). 347eac174f2Safresh1 348eac174f2Safresh1 float => sub { 349eac174f2Safresh1 #printf "# Value '%s' handled by the 'float' sub.\n", $_[0]; 350eac174f2Safresh1 _float_constant(shift); 351eac174f2Safresh1 }, 352eac174f2Safresh1 353eac174f2Safresh1 # Take care of each number written as an integer (no decimal point or 354eac174f2Safresh1 # exponent) using binary, octal, or hexadecimal notation, e.g., "0b101" 355eac174f2Safresh1 # (binary), "0314" and "0o314" (octal), and "0x314" (hexadecimal). 356eac174f2Safresh1 357eac174f2Safresh1 binary => sub { 358eac174f2Safresh1 #printf "# Value '%s' handled by the 'binary' sub.\n", $_[0]; 359eac174f2Safresh1 my $str = shift; 360eac174f2Safresh1 return $obj_class -> new($str) if $str =~ /^0[XxBb]/; 361eac174f2Safresh1 $obj_class -> from_oct($str); 362b8851fccSafresh1 }; 363b8851fccSafresh1} 364b8851fccSafresh1 365eac174f2Safresh1sub inf () { $obj_class -> binf(); } 366eac174f2Safresh1sub NaN () { $obj_class -> bnan(); } 367eac174f2Safresh1 368eac174f2Safresh1# This should depend on the current accuracy/precision. Fixme! 369eac174f2Safresh1sub PI () { $obj_class -> new('3.141592653589793238462643383279502884197'); } 370eac174f2Safresh1sub e () { $obj_class -> new('2.718281828459045235360287471352662497757'); } 371b8851fccSafresh1 372b8851fccSafresh1sub bpi ($) { 373eac174f2Safresh1 my $up = Math::BigFloat -> upgrade(); # get current upgrading, if any ... 374eac174f2Safresh1 Math::BigFloat -> upgrade(undef); # ... and disable 375eac174f2Safresh1 my $x = Math::BigFloat -> bpi(@_); 376eac174f2Safresh1 Math::BigFloat -> upgrade($up); # reset the upgrading 377eac174f2Safresh1 return $obj_class -> new($x); 378b8851fccSafresh1} 379b8851fccSafresh1 380b8851fccSafresh1sub bexp ($$) { 381eac174f2Safresh1 my $up = Math::BigFloat -> upgrade(); # get current upgrading, if any ... 382eac174f2Safresh1 Math::BigFloat -> upgrade(undef); # ... and disable 383eac174f2Safresh1 my $x = Math::BigFloat -> new(shift); 384eac174f2Safresh1 $x -> bexp(@_); 385eac174f2Safresh1 Math::BigFloat -> upgrade($up); # reset the upgrading 386eac174f2Safresh1 return $obj_class -> new($x); 387b8851fccSafresh1} 388b8851fccSafresh1 389b8851fccSafresh11; 390b8851fccSafresh1 391b8851fccSafresh1__END__ 392b8851fccSafresh1 393b8851fccSafresh1=pod 394b8851fccSafresh1 395b8851fccSafresh1=head1 NAME 396b8851fccSafresh1 397eac174f2Safresh1bigrat - transparent big rational number support for Perl 398b8851fccSafresh1 399b8851fccSafresh1=head1 SYNOPSIS 400b8851fccSafresh1 401b8851fccSafresh1 use bigrat; 402b8851fccSafresh1 403eac174f2Safresh1 print 2 + 4.5; # Math::BigRat 13/2 404eac174f2Safresh1 print 1/3 + 1/4; # Math::BigRat 7/12 405eac174f2Safresh1 print inf + 42; # Math::BigRat inf 406eac174f2Safresh1 print NaN * 7; # Math::BigRat NaN 407eac174f2Safresh1 print hex("0x1234567890123490"); # Perl v5.10.0 or later 408b8851fccSafresh1 409b8851fccSafresh1 { 410b8851fccSafresh1 no bigrat; 411eac174f2Safresh1 print 1/3; # 0.33333... 412b8851fccSafresh1 } 413b8851fccSafresh1 414eac174f2Safresh1 # for older Perls, import into current package: 415b8851fccSafresh1 use bigrat qw/hex oct/; 416eac174f2Safresh1 print hex("0x1234567890123490"); 417eac174f2Safresh1 print oct("01234567890123490"); 418b8851fccSafresh1 419b8851fccSafresh1=head1 DESCRIPTION 420b8851fccSafresh1 421eac174f2Safresh1All numeric literal in the given scope are converted to Math::BigRat objects. 422b8851fccSafresh1 423eac174f2Safresh1All operators (including basic math operations) except the range operator C<..> 424eac174f2Safresh1are overloaded. 425b8851fccSafresh1 426eac174f2Safresh1So, the following: 427b8851fccSafresh1 428eac174f2Safresh1 use bigrat; 429eac174f2Safresh1 $x = 1234; 430b8851fccSafresh1 431eac174f2Safresh1creates a Math::BigRat and stores a reference to in $x. This happens 432eac174f2Safresh1transparently and behind your back, so to speak. 433b8851fccSafresh1 434eac174f2Safresh1You can see this with the following: 435eac174f2Safresh1 436eac174f2Safresh1 perl -Mbigrat -le 'print ref(1234)' 437eac174f2Safresh1 438eac174f2Safresh1Since numbers are actually objects, you can call all the usual methods from 439eac174f2Safresh1Math::BigRat on them. This even works to some extent on expressions: 440eac174f2Safresh1 441eac174f2Safresh1 perl -Mbigrat -le '$x = 1234; print $x->bdec()' 442eac174f2Safresh1 perl -Mbigrat -le 'print 1234->copy()->binc();' 443eac174f2Safresh1 perl -Mbigrat -le 'print 1234->copy()->binc->badd(6);' 444eac174f2Safresh1 perl -Mbigrat -le 'print +(1234)->copy()->binc()' 445eac174f2Safresh1 446eac174f2Safresh1(Note that print doesn't do what you expect if the expression starts with 447eac174f2Safresh1'(' hence the C<+>) 448eac174f2Safresh1 449eac174f2Safresh1You can even chain the operations together as usual: 450eac174f2Safresh1 451eac174f2Safresh1 perl -Mbigrat -le 'print 1234->copy()->binc->badd(6);' 452eac174f2Safresh1 1241 453eac174f2Safresh1 454eac174f2Safresh1Please note the following does not work as expected (prints nothing), since 455eac174f2Safresh1overloading of '..' is not yet possible in Perl (as of v5.8.0): 456eac174f2Safresh1 457eac174f2Safresh1 perl -Mbigrat -le 'for (1..2) { print ref($_); }' 458eac174f2Safresh1 459eac174f2Safresh1=head2 Options 460eac174f2Safresh1 461eac174f2Safresh1C<bigrat> recognizes some options that can be passed while loading it via 462eac174f2Safresh1C<use>. The following options exist: 463eac174f2Safresh1 464eac174f2Safresh1=over 4 465eac174f2Safresh1 466eac174f2Safresh1=item a or accuracy 467eac174f2Safresh1 468eac174f2Safresh1This sets the accuracy for all math operations. The argument must be greater 469eac174f2Safresh1than or equal to zero. See Math::BigInt's bround() method for details. 470eac174f2Safresh1 471eac174f2Safresh1 perl -Mbigrat=a,50 -le 'print sqrt(20)' 472eac174f2Safresh1 473eac174f2Safresh1Note that setting precision and accuracy at the same time is not possible. 474eac174f2Safresh1 475eac174f2Safresh1=item p or precision 476eac174f2Safresh1 477eac174f2Safresh1This sets the precision for all math operations. The argument can be any 478eac174f2Safresh1integer. Negative values mean a fixed number of digits after the dot, while a 479eac174f2Safresh1positive value rounds to this digit left from the dot. 0 means round to integer. 480eac174f2Safresh1See Math::BigInt's bfround() method for details. 481eac174f2Safresh1 482eac174f2Safresh1 perl -Mbigrat=p,-50 -le 'print sqrt(20)' 483eac174f2Safresh1 484eac174f2Safresh1Note that setting precision and accuracy at the same time is not possible. 485eac174f2Safresh1 486eac174f2Safresh1=item t or trace 487eac174f2Safresh1 488eac174f2Safresh1This enables a trace mode and is primarily for debugging. 489eac174f2Safresh1 490eac174f2Safresh1=item l, lib, try, or only 491eac174f2Safresh1 492eac174f2Safresh1Load a different math lib, see L<Math Library>. 493eac174f2Safresh1 494eac174f2Safresh1 perl -Mbigrat=l,GMP -e 'print 2 ** 512' 495eac174f2Safresh1 perl -Mbigrat=lib,GMP -e 'print 2 ** 512' 496eac174f2Safresh1 perl -Mbigrat=try,GMP -e 'print 2 ** 512' 497eac174f2Safresh1 perl -Mbigrat=only,GMP -e 'print 2 ** 512' 498eac174f2Safresh1 499eac174f2Safresh1=item hex 500eac174f2Safresh1 501eac174f2Safresh1Override the built-in hex() method with a version that can handle big numbers. 502eac174f2Safresh1This overrides it by exporting it to the current package. Under Perl v5.10.0 and 503eac174f2Safresh1higher, this is not so necessary, as hex() is lexically overridden in the 504eac174f2Safresh1current scope whenever the C<bigrat> pragma is active. 505eac174f2Safresh1 506eac174f2Safresh1=item oct 507eac174f2Safresh1 508eac174f2Safresh1Override the built-in oct() method with a version that can handle big numbers. 509eac174f2Safresh1This overrides it by exporting it to the current package. Under Perl v5.10.0 and 510eac174f2Safresh1higher, this is not so necessary, as oct() is lexically overridden in the 511eac174f2Safresh1current scope whenever the C<bigrat> pragma is active. 512eac174f2Safresh1 513eac174f2Safresh1=item v or version 514eac174f2Safresh1 515eac174f2Safresh1this prints out the name and version of the modules and then exits. 516eac174f2Safresh1 517eac174f2Safresh1 perl -Mbigrat=v 518eac174f2Safresh1 519eac174f2Safresh1=back 520b8851fccSafresh1 521b8851fccSafresh1=head2 Math Library 522b8851fccSafresh1 523eac174f2Safresh1Math with the numbers is done (by default) by a backend library module called 524eac174f2Safresh1Math::BigInt::Calc. The default is equivalent to saying: 525b8851fccSafresh1 526b8851fccSafresh1 use bigrat lib => 'Calc'; 527b8851fccSafresh1 528eac174f2Safresh1you can change this by using: 529b8851fccSafresh1 530eac174f2Safresh1 use bigrat lib => 'GMP'; 531b8851fccSafresh1 532eac174f2Safresh1The following would first try to find Math::BigInt::Foo, then Math::BigInt::Bar, 533eac174f2Safresh1and if this also fails, revert to Math::BigInt::Calc: 534b8851fccSafresh1 535b8851fccSafresh1 use bigrat lib => 'Foo,Math::BigInt::Bar'; 536b8851fccSafresh1 537eac174f2Safresh1Using c<lib> warns if none of the specified libraries can be found and 538eac174f2Safresh1L<Math::BigInt> fell back to one of the default libraries. To suppress this 539eac174f2Safresh1warning, use c<try> instead: 540b8851fccSafresh1 541eac174f2Safresh1 use bigrat try => 'GMP'; 542b8851fccSafresh1 543b8851fccSafresh1If you want the code to die instead of falling back, use C<only> instead: 544b8851fccSafresh1 545eac174f2Safresh1 use bigrat only => 'GMP'; 546b8851fccSafresh1 547eac174f2Safresh1Please see the respective module documentation for further details. 548b8851fccSafresh1 549eac174f2Safresh1=head2 Method calls 550b8851fccSafresh1 551eac174f2Safresh1Since all numbers are now objects, you can use all methods that are part of the 552eac174f2Safresh1Math::BigRat API. 553b8851fccSafresh1 554eac174f2Safresh1But a warning is in order. When using the following to make a copy of a number, 555eac174f2Safresh1only a shallow copy will be made. 556eac174f2Safresh1 557eac174f2Safresh1 $x = 9; $y = $x; 558eac174f2Safresh1 $x = $y = 7; 559eac174f2Safresh1 560eac174f2Safresh1Using the copy or the original with overloaded math is okay, e.g., the following 561eac174f2Safresh1work: 562eac174f2Safresh1 563eac174f2Safresh1 $x = 9; $y = $x; 564eac174f2Safresh1 print $x + 1, " ", $y,"\n"; # prints 10 9 565eac174f2Safresh1 566eac174f2Safresh1but calling any method that modifies the number directly will result in B<both> 567eac174f2Safresh1the original and the copy being destroyed: 568eac174f2Safresh1 569eac174f2Safresh1 $x = 9; $y = $x; 570eac174f2Safresh1 print $x->badd(1), " ", $y,"\n"; # prints 10 10 571eac174f2Safresh1 572eac174f2Safresh1 $x = 9; $y = $x; 573eac174f2Safresh1 print $x->binc(1), " ", $y,"\n"; # prints 10 10 574eac174f2Safresh1 575eac174f2Safresh1 $x = 9; $y = $x; 576eac174f2Safresh1 print $x->bmul(2), " ", $y,"\n"; # prints 18 18 577eac174f2Safresh1 578eac174f2Safresh1Using methods that do not modify, but test that the contents works: 579eac174f2Safresh1 580eac174f2Safresh1 $x = 9; $y = $x; 581eac174f2Safresh1 $z = 9 if $x->is_zero(); # works fine 582eac174f2Safresh1 583eac174f2Safresh1See the documentation about the copy constructor and C<=> in overload, as well 584eac174f2Safresh1as the documentation in Math::BigFloat for further details. 585b8851fccSafresh1 586b8851fccSafresh1=head2 Methods 587b8851fccSafresh1 588eac174f2Safresh1=over 4 589b8851fccSafresh1 590b8851fccSafresh1=item inf() 591b8851fccSafresh1 592eac174f2Safresh1A shortcut to return Math::BigRat->binf(). Useful because Perl does not always 593b8851fccSafresh1handle bareword C<inf> properly. 594b8851fccSafresh1 595b8851fccSafresh1=item NaN() 596b8851fccSafresh1 597eac174f2Safresh1A shortcut to return Math::BigRat->bnan(). Useful because Perl does not always 598b8851fccSafresh1handle bareword C<NaN> properly. 599b8851fccSafresh1 600b8851fccSafresh1=item e 601b8851fccSafresh1 602b8851fccSafresh1 # perl -Mbigrat=e -wle 'print e' 603b8851fccSafresh1 604b8851fccSafresh1Returns Euler's number C<e>, aka exp(1). 605b8851fccSafresh1 606b8851fccSafresh1=item PI 607b8851fccSafresh1 608b8851fccSafresh1 # perl -Mbigrat=PI -wle 'print PI' 609b8851fccSafresh1 610b8851fccSafresh1Returns PI. 611b8851fccSafresh1 612b8851fccSafresh1=item bexp() 613b8851fccSafresh1 614b8851fccSafresh1 bexp($power, $accuracy); 615b8851fccSafresh1 616eac174f2Safresh1Returns Euler's number C<e> raised to the appropriate power, to the wanted 617eac174f2Safresh1accuracy. 618b8851fccSafresh1 619b8851fccSafresh1Example: 620b8851fccSafresh1 621b8851fccSafresh1 # perl -Mbigrat=bexp -wle 'print bexp(1,80)' 622b8851fccSafresh1 623b8851fccSafresh1=item bpi() 624b8851fccSafresh1 625b8851fccSafresh1 bpi($accuracy); 626b8851fccSafresh1 627b8851fccSafresh1Returns PI to the wanted accuracy. 628b8851fccSafresh1 629b8851fccSafresh1Example: 630b8851fccSafresh1 631b8851fccSafresh1 # perl -Mbigrat=bpi -wle 'print bpi(80)' 632b8851fccSafresh1 633eac174f2Safresh1=item accuracy() 634b8851fccSafresh1 635eac174f2Safresh1Set or get the accuracy. 636eac174f2Safresh1 637eac174f2Safresh1=item precision() 638eac174f2Safresh1 639eac174f2Safresh1Set or get the precision. 640eac174f2Safresh1 641eac174f2Safresh1=item round_mode() 642eac174f2Safresh1 643eac174f2Safresh1Set or get the rounding mode. 644eac174f2Safresh1 645eac174f2Safresh1=item div_scale() 646eac174f2Safresh1 647eac174f2Safresh1Set or get the division scale. 648b8851fccSafresh1 649b8851fccSafresh1=item in_effect() 650b8851fccSafresh1 651b8851fccSafresh1 use bigrat; 652b8851fccSafresh1 653b8851fccSafresh1 print "in effect\n" if bigrat::in_effect; # true 654b8851fccSafresh1 { 655b8851fccSafresh1 no bigrat; 656b8851fccSafresh1 print "in effect\n" if bigrat::in_effect; # false 657b8851fccSafresh1 } 658b8851fccSafresh1 659b8851fccSafresh1Returns true or false if C<bigrat> is in effect in the current scope. 660b8851fccSafresh1 661b8851fccSafresh1This method only works on Perl v5.9.4 or later. 662b8851fccSafresh1 663b8851fccSafresh1=back 664b8851fccSafresh1 665b8851fccSafresh1=head1 CAVEATS 666b8851fccSafresh1 667eac174f2Safresh1=over 4 668eac174f2Safresh1 669eac174f2Safresh1=item Hexadecimal, octal, and binary floating point literals 670eac174f2Safresh1 671eac174f2Safresh1Perl (and this module) accepts hexadecimal, octal, and binary floating point 672eac174f2Safresh1literals, but use them with care with Perl versions before v5.32.0, because some 673eac174f2Safresh1versions of Perl silently give the wrong result. 674b8851fccSafresh1 675b8851fccSafresh1=item Operator vs literal overloading 676b8851fccSafresh1 677eac174f2Safresh1C<bigrat> works by overloading handling of integer and floating point literals, 678eac174f2Safresh1converting them to L<Math::BigRat> objects. 679b8851fccSafresh1 680eac174f2Safresh1This means that arithmetic involving only string values or string literals are 681eac174f2Safresh1performed using Perl's built-in operators. 682b8851fccSafresh1 683b8851fccSafresh1For example: 684b8851fccSafresh1 685b8851fccSafresh1 use bigrat; 686b8851fccSafresh1 my $x = "900000000000000009"; 687b8851fccSafresh1 my $y = "900000000000000007"; 688b8851fccSafresh1 print $x - $y; 689b8851fccSafresh1 690eac174f2Safresh1outputs C<0> on default 32-bit builds, since C<bigrat> never sees the string 691eac174f2Safresh1literals. To ensure the expression is all treated as C<Math::BigRat> objects, 692eac174f2Safresh1use a literal number in the expression: 693b8851fccSafresh1 694b8851fccSafresh1 print +(0+$x) - $y; 695b8851fccSafresh1 696eac174f2Safresh1=item Ranges 697eac174f2Safresh1 698eac174f2Safresh1Perl does not allow overloading of ranges, so you can neither safely use ranges 699eac174f2Safresh1with C<bigrat> endpoints, nor is the iterator variable a C<Math::BigRat>. 700eac174f2Safresh1 701eac174f2Safresh1 use 5.010; 702eac174f2Safresh1 for my $i (12..13) { 703eac174f2Safresh1 for my $j (20..21) { 704eac174f2Safresh1 say $i ** $j; # produces a floating-point number, 705eac174f2Safresh1 # not an object 706eac174f2Safresh1 } 707eac174f2Safresh1 } 708eac174f2Safresh1 709b8851fccSafresh1=item in_effect() 710b8851fccSafresh1 711b8851fccSafresh1This method only works on Perl v5.9.4 or later. 712b8851fccSafresh1 713b8851fccSafresh1=item hex()/oct() 714b8851fccSafresh1 715eac174f2Safresh1C<bigrat> overrides these routines with versions that can also handle big 716eac174f2Safresh1integer values. Under Perl prior to version v5.9.4, however, this will not 717eac174f2Safresh1happen unless you specifically ask for it with the two import tags "hex" and 718eac174f2Safresh1"oct" - and then it will be global and cannot be disabled inside a scope with 719eac174f2Safresh1C<no bigrat>: 720b8851fccSafresh1 721eac174f2Safresh1 use bigrat qw/hex oct/; 722b8851fccSafresh1 723b8851fccSafresh1 print hex("0x1234567890123456"); 724b8851fccSafresh1 { 725eac174f2Safresh1 no bigrat; 726b8851fccSafresh1 print hex("0x1234567890123456"); 727b8851fccSafresh1 } 728b8851fccSafresh1 729b8851fccSafresh1The second call to hex() will warn about a non-portable constant. 730b8851fccSafresh1 731b8851fccSafresh1Compare this to: 732b8851fccSafresh1 733eac174f2Safresh1 use bigrat; 734b8851fccSafresh1 735b8851fccSafresh1 # will warn only under Perl older than v5.9.4 736b8851fccSafresh1 print hex("0x1234567890123456"); 737b8851fccSafresh1 738b8851fccSafresh1=back 739b8851fccSafresh1 740b8851fccSafresh1=head1 EXAMPLES 741b8851fccSafresh1 742b8851fccSafresh1 perl -Mbigrat -le 'print sqrt(33)' 743eac174f2Safresh1 perl -Mbigrat -le 'print 2**255' 744eac174f2Safresh1 perl -Mbigrat -le 'print 4.5+2**255' 745b8851fccSafresh1 perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3' 746b8851fccSafresh1 perl -Mbigrat -le 'print 12->is_odd()'; 747eac174f2Safresh1 perl -Mbigrat=l,GMP -le 'print 7 ** 7777' 748b8851fccSafresh1 7499f11ffb7Safresh1=head1 BUGS 7509f11ffb7Safresh1 751eac174f2Safresh1Please report any bugs or feature requests to 752eac174f2Safresh1C<bug-bignum at rt.cpan.org>, or through the web interface at 753eac174f2Safresh1L<https://rt.cpan.org/Ticket/Create.html?Queue=bignum> (requires login). 754eac174f2Safresh1We will be notified, and then you'll automatically be notified of 755eac174f2Safresh1progress on your bug as I make changes. 7569f11ffb7Safresh1 7579f11ffb7Safresh1=head1 SUPPORT 7589f11ffb7Safresh1 7599f11ffb7Safresh1You can find documentation for this module with the perldoc command. 7609f11ffb7Safresh1 7619f11ffb7Safresh1 perldoc bigrat 7629f11ffb7Safresh1 763eac174f2Safresh1You can also look for information at: 7649f11ffb7Safresh1 765eac174f2Safresh1=over 4 766eac174f2Safresh1 767eac174f2Safresh1=item * GitHub 768eac174f2Safresh1 769eac174f2Safresh1L<https://github.com/pjacklam/p5-bignum> 770eac174f2Safresh1 771eac174f2Safresh1=item * RT: CPAN's request tracker 772eac174f2Safresh1 773eac174f2Safresh1L<https://rt.cpan.org/Dist/Display.html?Name=bignum> 774eac174f2Safresh1 775eac174f2Safresh1=item * MetaCPAN 776eac174f2Safresh1 777eac174f2Safresh1L<https://metacpan.org/release/bignum> 778eac174f2Safresh1 779eac174f2Safresh1=item * CPAN Testers Matrix 780eac174f2Safresh1 781eac174f2Safresh1L<http://matrix.cpantesters.org/?dist=bignum> 782eac174f2Safresh1 783eac174f2Safresh1=back 7849f11ffb7Safresh1 785b8851fccSafresh1=head1 LICENSE 786b8851fccSafresh1 787b8851fccSafresh1This program is free software; you may redistribute it and/or modify it under 788b8851fccSafresh1the same terms as Perl itself. 789b8851fccSafresh1 790b8851fccSafresh1=head1 SEE ALSO 791b8851fccSafresh1 7929f11ffb7Safresh1L<bignum> and L<bigint>. 793b8851fccSafresh1 7949f11ffb7Safresh1L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigRat> and L<Math::Big> as well as 7959f11ffb7Safresh1L<Math::BigInt::FastCalc>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>. 796b8851fccSafresh1 797b8851fccSafresh1=head1 AUTHORS 798b8851fccSafresh1 7999f11ffb7Safresh1=over 4 8009f11ffb7Safresh1 8019f11ffb7Safresh1=item * 8029f11ffb7Safresh1 803b8851fccSafresh1(C) by Tels L<http://bloodgate.com/> in early 2002 - 2007. 804b8851fccSafresh1 8059f11ffb7Safresh1=item * 8069f11ffb7Safresh1 807eac174f2Safresh1Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt>, 2014-. 8089f11ffb7Safresh1 8099f11ffb7Safresh1=back 8109f11ffb7Safresh1 811b8851fccSafresh1=cut 812