home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 March / PCWorld_2003-03_cd.bin / Software / Topware / activeperl / ActivePerl / Perl / lib / bignum.pm < prev    next >
Encoding:
Perl POD Document  |  2002-06-19  |  9.1 KB  |  325 lines

  1. package bignum;
  2. require 5.005;
  3.  
  4. $VERSION = '0.11';
  5. use Exporter;
  6. @ISA =       qw( Exporter );
  7. @EXPORT_OK = qw( ); 
  8.  
  9. use strict;
  10.  
  11. ############################################################################## 
  12.  
  13. # These are all alike, and thus faked by AUTOLOAD
  14.  
  15. my @faked = qw/round_mode accuracy precision div_scale/;
  16. use vars qw/$VERSION $AUTOLOAD $_lite/;        # _lite for testsuite
  17.  
  18. sub AUTOLOAD
  19.   {
  20.   my $name = $AUTOLOAD;
  21.  
  22.   $name =~ s/.*:://;    # split package
  23.   no strict 'refs';
  24.   foreach my $n (@faked)
  25.     {
  26.     if ($n eq $name)
  27.       {
  28.       *{"bignum::$name"} = sub 
  29.         {
  30.         my $self = shift;
  31.         no strict 'refs';
  32.         if (defined $_[0])
  33.           {
  34.           Math::BigInt->$name($_[0]);
  35.           Math::BigFloat->$name($_[0]);
  36.           }
  37.         return Math::BigInt->$name();
  38.         };
  39.       return &$name;
  40.       }
  41.     }
  42.  
  43.   # delayed load of Carp and avoid recursion
  44.   require Carp;
  45.   Carp::croak ("Can't call bignum\-\>$name, not a valid method");
  46.   }
  47.  
  48. sub upgrade
  49.   {
  50.   my $self = shift;
  51.   no strict 'refs';
  52. #  if (defined $_[0])
  53. #    {
  54. #    $Math::BigInt::upgrade = $_[0];
  55. #    $Math::BigFloat::upgrade = $_[0];
  56. #    }
  57.   return $Math::BigInt::upgrade;
  58.   }
  59.  
  60. sub import 
  61.   {
  62.   my $self = shift;
  63.  
  64.   # some defaults
  65.   my $lib = 'Calc';
  66.   my $upgrade = 'Math::BigFloat';
  67.   my $downgrade = 'Math::BigInt';
  68.  
  69.   my @import = ( ':constant' );                # drive it w/ constant
  70.   my @a = @_; my $l = scalar @_; my $j = 0;
  71.   my ($ver,$trace);                    # version? trace?
  72.   my ($a,$p);                        # accuracy, precision
  73.   for ( my $i = 0; $i < $l ; $i++,$j++ )
  74.     {
  75.     if ($_[$i] eq 'upgrade')
  76.       {
  77.       # this causes upgrading
  78.       $upgrade = $_[$i+1];        # or undef to disable
  79.       my $s = 2; $s = 1 if @a-$j < 2;    # avoid "can not modify non-existant..."
  80.       splice @a, $j, $s; $j -= $s; $i++;
  81.       }
  82.     elsif ($_[$i] eq 'downgrade')
  83.       {
  84.       # this causes downgrading
  85.       $downgrade = $_[$i+1];        # or undef to disable
  86.       my $s = 2; $s = 1 if @a-$j < 2;    # avoid "can not modify non-existant..."
  87.       splice @a, $j, $s; $j -= $s; $i++;
  88.       }
  89.     elsif ($_[$i] =~ /^(l|lib)$/)
  90.       {
  91.       # this causes a different low lib to take care...
  92.       $lib = $_[$i+1] || '';
  93.       my $s = 2; $s = 1 if @a-$j < 2;    # avoid "can not modify non-existant..."
  94.       splice @a, $j, $s; $j -= $s; $i++;
  95.       }
  96.     elsif ($_[$i] =~ /^(a|accuracy)$/)
  97.       {
  98.       $a = $_[$i+1];
  99.       my $s = 2; $s = 1 if @a-$j < 2;    # avoid "can not modify non-existant..."
  100.       splice @a, $j, $s; $j -= $s; $i++;
  101.       }
  102.     elsif ($_[$i] =~ /^(p|precision)$/)
  103.       {
  104.       $p = $_[$i+1];
  105.       my $s = 2; $s = 1 if @a-$j < 2;    # avoid "can not modify non-existant..."
  106.       splice @a, $j, $s; $j -= $s; $i++;
  107.       }
  108.     elsif ($_[$i] =~ /^(v|version)$/)
  109.       {
  110.       $ver = 1;
  111.       splice @a, $j, 1; $j --;
  112.       }
  113.     elsif ($_[$i] =~ /^(t|trace)$/)
  114.       {
  115.       $trace = 1;
  116.       splice @a, $j, 1; $j --;
  117.       }
  118.     else { die "unknown option $_[$i]"; }
  119.     }
  120.   my $class;
  121.   $_lite = 0;                    # using M::BI::L ?
  122.   if ($trace)
  123.     {
  124.     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
  125.     $upgrade = 'Math::BigFloat::Trace';    
  126.     }
  127.   else
  128.     {
  129.     # see if we can find Math::BigInt::Lite
  130.     if (!defined $a && !defined $p)        # rounding won't work to well
  131.       {
  132.       eval 'require Math::BigInt::Lite;';
  133.       if ($@ eq '')
  134.         {
  135.         @import = ( );                # :constant in Lite, not MBI
  136.         Math::BigInt::Lite->import( ':constant' );
  137.         $_lite= 1;                # signal okay
  138.         }
  139.       }
  140.     require Math::BigInt if $_lite == 0;    # not already loaded?
  141.     $class = 'Math::BigInt';            # regardless of MBIL or not
  142.     } 
  143.   # Math::BigInt::Trace or plain Math::BigInt
  144.   $class->import(@import, upgrade => $upgrade, lib => $lib);
  145.  
  146.   if ($trace)
  147.     {
  148.     require Math::BigFloat::Trace; $class = 'Math::BigFloat::Trace';
  149.     $downgrade = 'Math::BigInt::Trace';    
  150.     }
  151.   else
  152.     {
  153.     require Math::BigFloat; $class = 'Math::BigFloat';
  154.     }
  155.   $class->import(':constant','downgrade',$downgrade);
  156.  
  157.   bignum->accuracy($a) if defined $a;
  158.   bignum->precision($p) if defined $p;
  159.   if ($ver)
  160.     {
  161.     print "bignum\t\t\t v$VERSION\n";
  162.     print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
  163.     print "Math::BigInt\t\t v$Math::BigInt::VERSION";
  164.     my $config = Math::BigInt->config();
  165.     print " lib => $config->{lib} v$config->{lib_version}\n";
  166.     print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
  167.     exit;
  168.     }
  169.   }
  170.  
  171. 1;
  172.  
  173. __END__
  174.  
  175. =head1 NAME
  176.  
  177. bignum - Transparent BigNumber support for Perl
  178.  
  179. =head1 SYNOPSIS
  180.  
  181.   use bignum;
  182.  
  183.   $x = 2 + 4.5,"\n";            # BigFloat 6.5
  184.   print 2 ** 512 * 0.1;            # really is what you think it is
  185.  
  186. =head1 DESCRIPTION
  187.  
  188. All operators (including basic math operations) are overloaded. Integer and
  189. floating-point constants are created as proper BigInts or BigFloats,
  190. respectively.
  191.  
  192. =head2 OPTIONS
  193.  
  194. bignum recognizes some options that can be passed while loading it via use.
  195. The options can (currently) be either a single letter form, or the long form.
  196. The following options exist:
  197.  
  198. =over 2
  199.  
  200. =item a or accuracy
  201.  
  202. This sets the accuracy for all math operations. The argument must be greater
  203. than or equal to zero. See Math::BigInt's bround() function for details.
  204.  
  205.     perl -Mbignum=a,50 -le 'print sqrt(20)'
  206.  
  207. =item p or precision
  208.  
  209. This sets the precision for all math operations. The argument can be any
  210. integer. Negative values mean a fixed number of digits after the dot, while
  211. a positive value rounds to this digit left from the dot. 0 or 1 mean round to
  212. integer. See Math::BigInt's bfround() function for details.
  213.  
  214.     perl -Mbignum=p,-50 -le 'print sqrt(20)'
  215.  
  216. =item t or trace
  217.  
  218. This enables a trace mode and is primarily for debugging bignum or
  219. Math::BigInt/Math::BigFloat.
  220.  
  221. =item l or lib
  222.  
  223. Load a different math lib, see L<MATH LIBRARY>.
  224.  
  225.     perl -Mbignum=l,GMP -e 'print 2 ** 512'
  226.  
  227. Currently there is no way to specify more than one library on the command
  228. line. This will be hopefully fixed soon ;)
  229.  
  230. =item v or version
  231.  
  232. This prints out the name and version of all modules used and then exits.
  233.  
  234.     perl -Mbignum=v -e ''
  235.  
  236. =head2 MATH LIBRARY
  237.  
  238. Math with the numbers is done (by default) by a module called
  239. Math::BigInt::Calc. This is equivalent to saying:
  240.  
  241.     use bignum lib => 'Calc';
  242.  
  243. You can change this by using:
  244.  
  245.     use bignum lib => 'BitVect';
  246.  
  247. The following would first try to find Math::BigInt::Foo, then
  248. Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
  249.  
  250.     use bignum lib => 'Foo,Math::BigInt::Bar';
  251.  
  252. Please see respective module documentation for further details.
  253.  
  254. =head2 INTERNAL FORMAT
  255.  
  256. The numbers are stored as objects, and their internals might change at anytime,
  257. especially between math operations. The objects also might belong to different
  258. classes, like Math::BigInt, or Math::BigFLoat. Mixing them together, even
  259. with normal scalars is not extraordinary, but normal and expected.
  260.  
  261. You should not depend on the internal format, all accesses must go through
  262. accessor methods. E.g. looking at $x->{sign} is not a bright idea since there
  263. is no guaranty that the object in question has such a hashkey, nor is a hash
  264. underneath at all.
  265.  
  266. =head2 SIGN
  267.  
  268. The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
  269. You can access it with the sign() method.
  270.  
  271. A sign of 'NaN' is used to represent the result when input arguments are not
  272. numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
  273. minus infinity. You will get '+inf' when dividing a positive number by 0, and
  274. '-inf' when dividing any negative number by 0.
  275.  
  276. =head2 METHODS
  277.  
  278. Since all numbers are now objects, you can use all functions that are part of
  279. the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
  280. the fxxx() notation, though. This makes it possible that the underlying object
  281. might morph into a different class than BigFloat.
  282.  
  283. =head1 MODULES USED
  284.  
  285. C<bignum> is just a thin wrapper around various modules of the Math::BigInt
  286. family. Think of it as the head of the family, who runs the shop, and orders
  287. the others to do the work.
  288.  
  289. The following modules are currently used by bignum:
  290.  
  291.     Math::BigInt::Lite    (for speed, and only if it is loadable)
  292.     Math::BigInt
  293.     Math::BigFloat
  294.  
  295. =head1 EXAMPLES
  296.  
  297. Some cool command line examples to impress the Python crowd ;)
  298.  
  299.     perl -Mbignum -le 'print sqrt(33)'
  300.     perl -Mbignum -le 'print 2*255'
  301.     perl -Mbignum -le 'print 4.5+2*255'
  302.     perl -Mbignum -le 'print 3/7 + 5/7 + 8/3'
  303.     perl -Mbignum -le 'print 123->is_odd()'
  304.     perl -Mbignum -le 'print log(2)'
  305.     perl -Mbignum -le 'print 2 ** 0.5'
  306.     perl -Mbignum=a,65 -le 'print 2 ** 0.2'
  307.  
  308. =head1 LICENSE
  309.  
  310. This program is free software; you may redistribute it and/or modify it under
  311. the same terms as Perl itself.
  312.  
  313. =head1 SEE ALSO
  314.  
  315. Especially L<bigrat> as in C<perl -Mbigrat -le 'print 1/3+1/4'>.
  316.  
  317. L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
  318. as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and  L<Math::BigInt::GMP>.
  319.  
  320. =head1 AUTHORS
  321.  
  322. (C) by Tels L<http://bloodgate.com/> in early 2002.
  323.  
  324. =cut
  325.