Current Path : /usr/local/lib/perl5/site_perl/5.8.9/mach/Math/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //usr/local/lib/perl5/site_perl/5.8.9/mach/Math/GMP.pm |
package Math::GMP; # Math::GMP, a Perl module for high-speed arbitrary size integer # calculations # Copyright (C) 2000-2008 James H. Turner # Copyright (C) 2008 Greg Sabino Mullane # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # You can contact the author at chip@redhat.com, chipt@cpan.org, or by mail: # Chip Turner # Red Hat Inc. # 2600 Meridian Park Blvd # Durham, NC 27713 use strict; use warnings; use 5.006; use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD); use overload '""' => \&stringify, '0+' => \&intify, '<=>' => \&op_spaceship, 'cmp' => \&op_cmp, '+' => \&op_add, '-' => \&op_sub, '&' => \&op_and, '^' => \&op_xor, '|' => \&op_or, '%' => \&op_mod, '**' => \&op_pow, '*' => \&op_mul, '/' => \&op_div; require Exporter; require DynaLoader; require AutoLoader; @ISA = qw(Exporter DynaLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. our $VERSION = '2.05'; sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() # XS function. If a constant is not found then control is passed # to the AUTOLOAD in AutoLoader. my $constname; ($constname = $AUTOLOAD) =~ s/.*:://; croak '& not defined' if $constname eq 'constant'; my $val = constant($constname, @_ ? $_[0] : 0); if ($! != 0) { if ($! =~ /Invalid/) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { croak "Your vendor has not defined Math::GMP macro $constname"; } } no strict 'refs'; ## no critic *$AUTOLOAD = sub () { $val }; goto &$AUTOLOAD; } bootstrap Math::GMP $VERSION; use strict; sub import { shift; return unless @_; die "unknown import: @_" unless @_ == 1 and $_[0] eq ':constant'; overload::constant integer => sub { Math::GMP->new(shift) }; return; } sub new { my $class = shift; my $ival = shift || 0; my $base = shift; $ival =~ s/^\+//; $ival =~ s/[ _]//g; my $ret; if ($base) { $ret = Math::GMP::new_from_scalar_with_base($ival, $base); } else { $ival = 0 if $ival =~ /[^\d\-xA-Fa-f]/; $ret = Math::GMP::new_from_scalar($ival); } return $ret; } BEGIN { *DESTROY = \&Math::GMP::destroy; } sub add { croak 'add: not enough arguments, two required' if @_ < 2; my $ret = Math::GMP->new(0); add_to_self($ret, shift) while @_; return $ret; } sub stringify { return Math::GMP::stringify_gmp($_[0]); } sub intify { return Math::GMP::intify_gmp($_[0]); } sub promote { return $_[0] if ref $_[0] eq 'Math::GMP'; return Math::GMP::new_from_scalar($_[0] || 0); } sub gcd { return gcd_two(promote(shift), promote(shift)); } sub bgcd { return gcd_two(promote(shift), promote(shift)); } sub legendre { return gmp_legendre(promote(shift), promote(shift)); } sub jacobi { return gmp_jacobi(promote(shift), promote(shift)); } sub probab_prime { my $x = shift; my $reps = shift; return gmp_probab_prime(promote($x), $reps); } sub op_add { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return add_two(promote($n), promote($m)); } sub op_sub { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return sub_two(promote($n), promote($m)); } sub op_mul { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return mul_two(promote($n), promote($m)); } sub op_div { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return div_two(promote($n), promote($m)); } sub bdiv { return bdiv_two(promote(shift), promote(shift)); } sub op_mod { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return mod_two(promote($n), promote($m)); } sub op_cmp { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return cmp_two(stringify(promote($n)), stringify(promote($m))); } sub op_spaceship { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; my $x = cmp_two(promote($n), promote($m)); return $x < 0 ? -1 : $x > 0 ? 1 : 0; } sub op_pow { my ($m, $n) = @_; ($n, $m) = ($m, $n) if $_[2]; return pow_two(promote($m), int($n)); } sub op_and { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return and_two(promote($n), promote($m)); } sub op_xor { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return xor_two(promote($n), promote($m)); } sub op_or { my ($n, $m) = @_; ($n, $m) = ($m, $n) if $_[2]; return or_two(promote($n), promote($m)); } sub bior { return or_two(promote(shift), promote(shift)); } sub band { return and_two(promote(shift), promote(shift)); } sub bxor { return xor_two(promote(shift), promote(shift)); } sub bfac { return gmp_fac(int(shift)); } sub fibonacci { return gmp_fib(int(shift)); } __END__ =head1 NAME Math::GMP - High speed arbitrary size integer math =head1 SYNOPSIS use Math::GMP; my $n = new Math::GMP 2; $n = $n ** (256*1024); $n = $n - 1; print "n is now $n\n"; =head1 DESCRIPTION Math::GMP was designed to be a drop-in replacement both for Math::BigInt and for regular integer arithmetic. Unlike BigInt, though, Math::GMP uses the GNU gmp library for all of its calculations, as opposed to straight Perl functions. This can result in speed improvements. The downside is that this module requires a C compiler to install -- a small tradeoff in most cases. Also, this module is not 100% compatible to Math::BigInt. A Math::GMP object can be used just as a normal numeric scalar would be -- the module overloads most of the normal arithmetic operators to provide as seamless an interface as possible. However, if you need a perfect interface, you can do the following: use Math::GMP qw(:constant); $n = 2 ** (256 * 1024); print "n is $n\n"; This would fail without the ':constant' since Perl would use normal doubles to compute the 250,000 bit number, and thereby overflow it into meaninglessness (smaller exponents yield less accurate data due to floating point rounding). =head1 METHODS Although the non-overload interface is not complete, the following functions do exist: =head2 new $x = Math::GMP->new(123); Creates a new Math::GMP object from the passed string or scalar. $x = Math::GMP->new('abcd', 36); Creates a new Math::GMP object from the first parameter which should be represented in the base specified by the second parameter. =head2 bfac $x = Math::GMP->new(5); $x->bfac(); # 1*2*3*4*5 = 120 Calculates the factorial of $x and modifies $x to contain the result. =head2 band $x = Math::GMP->new(6); $x->band(3); # 0b110 & 0b11 = 1 Calculates the bit-wise AND of it's two arguments and modifies the first argument. =head2 bxor $x = Math::GMP->new(6); $x->bxor(3); # 0b110 & 0b11 = 0b101 Calculates the bit-wise XOR of it's two arguments and modifies the first argument. =head2 bior $x = Math::GMP->new(6); $x->bior(3); # 0b110 & 0b11 = 0b111 Calculates the bit-wise OR of it's two arguments and modifies the first argument. =head2 bgcd $x = Math::GMP->new(6); $x->bgcd(4); # 6 / 2 = 2, 4 / 2 = 2 => 2 Calculates the Greatest Common Divisior of it's two arguments and returns the result. =head2 legendre =head2 jacobi =head2 fibonacci $x = Math::GMP->fibonacci(16); Calculates the n'th number in the Fibonacci sequence. =head2 probab_prime $x = Math::GMP->new(7); $x->probab_prime(10); Probabilistically Determines if the number is a prime. Argument is the number of checks to perform. Returns 0 if the number is definitely not a prime, 1 if it may be, and 2 if it is definitely is a prime. =head1 BUGS As of version 1.0, Math::GMP is mostly compatible with the old Math::BigInt version. It is not a full replacement for the rewritten Math::BigInt versions, though. See the L<SEE ALSO section|SEE ALSO> on how to achieve to use Math::GMP and retain full compatibility to Math::BigInt. There are some slight incompatibilities, such as output of positive numbers not being prefixed by a '+' sign. This is intentional. There are also some things missing, and not everything might work as expected. =head1 SEE ALSO Math::BigInt has a new interface to use a different library than the default pure Perl implementation. You can use, for instance, Math::GMP with it: use Math::BigInt lib => 'GMP'; If Math::GMP is not installed, it will fall back to it's own Perl implementation. See L<Math::BigInt> and L<Math::BigInt::GMP> or L<Math::BigInt::Pari> or L<Math::BigInt::BitVect>. =head1 AUTHOR Chip Turner <chip@redhat.com>, based on the old Math::BigInt by Mark Biggar and Ilya Zakharevich. Further extensive work provided by Tels <tels@bloodgate.com>. =cut