📄 gmp.pm
字号:
# GMP perl module# Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.## This file is part of the GNU MP Library.## The GNU MP Library is free software; you can redistribute it and/or modify# it under the terms of the GNU Lesser General Public License as published# by the Free Software Foundation; either version 2.1 of the License, or (at# your option) any later version.## The GNU MP 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 Lesser General Public# License for more details.## You should have received a copy of the GNU Lesser General Public License# along with the GNU MP Library; see the file COPYING.LIB. If not, write to# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,# MA 02111-1307, USA.# [Note: The above copyright notice is repeated in the documentation section# below, in order to get it into man pages etc generated by the various pod# conversions. When changing, be sure to update below too.]# This code is designed to work with perl 5.005, so it and the sub-packages# aren't as modern as they could be.package GMP;require Symbol;require Exporter;require DynaLoader;@ISA = qw(Exporter DynaLoader);@EXPORT = qw();@EXPORT_OK = qw(version);%EXPORT_TAGS = ('all' => [qw( get_d get_d_2exp get_si get_str integer_p printf sgn sprintf)], 'constants' => [()]);Exporter::export_ok_tags('all');$VERSION = '2.00';bootstrap GMP $VERSION;# The format string is cut up into "%" specifiers so GMP types can be# passed to GMP::sprintf_internal. Any "*"s are interpolated before# calling sprintf_internal, which saves worrying about variable# argument lists there.## Because sprintf_internal is only called after the conversion and# operand have been checked there won't be any crashes from a bad# format string.#sub sprintf { my $fmt = shift; my $out = ''; my ($pre, $dummy, $pat, $rest); while (($pre, $dummy, $pat, $rest) = ($fmt =~ /^((%%|[^%])*)(%[- +#.*hlLqv\d]*[bcdfeEgGinopsuxX])(.*)$/s)) { $out .= $pre; my $pat2 = $pat; # $pat with "*"s expanded my @params = (); # arguments per "*"s while ($pat2 =~ /[*]/) { my $arg = shift; $pat2 =~ s/[*]/$arg/; push @params, $arg; } if (UNIVERSAL::isa($_[0],"GMP::Mpz")) { if ($pat2 !~ /[dioxX]$/) { die "GMP::sprintf: unsupported output format for mpz: $pat2\n"; } $pat2 =~ s/(.)$/Z$1/; $out .= sprintf_internal ($pat2, shift); } elsif (UNIVERSAL::isa($_[0],"GMP::Mpq")) { if ($pat2 !~ /[dioxX]$/) { die "GMP::sprintf: unsupported output format for mpq: $pat2\n"; } $pat2 =~ s/(.)$/Q$1/; $out .= sprintf_internal ($pat2, shift); } elsif (UNIVERSAL::isa($_[0],"GMP::Mpf")) { if ($pat2 !~ /[eEfgG]$/) { die "GMP::sprintf: unsupported output format for mpf: $pat2\n"; } $pat2 =~ s/(.)$/F$1/; $out .= sprintf_internal ($pat2, shift); } elsif ($pat =~ /n$/) { # do it this way so h, l or V type modifiers are respected, and use a # dummy variable to avoid a warning about discarding the value my $dummy = sprintf "%s$pat", $out, $_[0]; shift; } else { $out .= sprintf $pat, @params, shift; } $fmt = $rest; } $out .= $fmt; return $out;}sub printf { if (ref($_[0]) eq 'GLOB') { my $h = Symbol::qualify_to_ref(shift, caller); print $h GMP::sprintf(@_); } else { print STDOUT GMP::sprintf(@_); }}1;__END__=head1 NAMEGMP - Perl interface to the GNU Multiple Precision Arithmetic Library=head1 SYNOPSIS use GMP; use GMP::Mpz; use GMP::Mpq; use GMP::Mpf; use GMP::Rand;=head1 DESCRIPTIONB<Note: Everything here is preliminary and may be subject to incompatiblechanges.>This module provides access to GNU MP arbitrary precision integers,rationals and floating point.No functions are exported from these packages by default, but can beselected in the usual way, or the tag :all for everything. use GMP::Mpz qw(gcd, lcm); # just these functions use GMP::Mpq qw(:all); # everything in mpq=head2 GMP::MpzThis class provides arbitrary precision integers. A new mpz can beconstructed with C<mpz>. The initial value can be an integer, float,string, mpz, mpq or mpf. Floats, mpq and mpf will be automaticallytruncated to an integer. use GMP::Mpz qw(:all); my $a = mpz(123); my $b = mpz("0xFFFF"); my $c = mpz(1.5); # truncatedThe following overloaded operators are available, and correspondingassignment forms like C<+=>,=over 4=item+ - * / % E<lt>E<lt> E<gt>E<gt> ** & | ^ ! E<lt> E<lt>= == != E<gt> E<gt>=E<lt>=E<gt> abs not sqrt=backC</> and C<%> round towards zero (as per the C<tdiv> functions in GMP).The following functions are available, behaving the same as thecorresponding GMP mpz functions,=over 4=itembin, cdiv, cdiv_2exp, clrbit, congruent_p, congruent_2exp_p,divexact, divisible_p, divisible_2exp_p, even_p, fac, fdiv, fdiv_2exp, fib,fib2, gcd, gcdext, hamdist, invert, jacobi, kronecker, lcm, lucnum, lucnum2,mod, mpz_export, mpz_import, nextprime, odd_p, perfect_power_p,perfect_square_p, popcount, powm, probab_prime_p, realloc, remove, root,roote, scan0, scan1, setbit, sizeinbase, sqrtrem, tdiv, tdiv_2exp, tstbit=backC<cdiv>, C<fdiv> and C<tdiv> and their C<2exp> variants return aquotient/remainder pair. C<fib2> returns a pair F[n] and F[n-1], similarlyC<lucnum2>. C<gcd> and C<lcm> accept a variable number of arguments (one ormore). C<gcdext> returns a triplet of gcd and two cofactors, for example use GMP::Mpz qw(:all); $a = 7257; $b = 10701; ($g, $x, $y) = gcdext ($a, $b); print "gcd($a,$b) is $g, and $g == $a*$x + $b*$y\n";C<mpz_import> and C<mpz_export> are so named to avoid the C<import> keyword.Their parameters are as follows, $z = mpz_import ($order, $size, $endian, $nails, $string); $string = mpz_export ($order, $size, $endian, $nails, $z);The order, size, endian and nails parameters are as per the corresponding Cfunctions. The string input for C<mpz_import> is interpreted as byte dataand must be a multiple of $size bytes. C<mpz_export> conversely returns astring of byte data, which will be a multiple of $size bytes.C<invert> returns the inverse, or undef if it doesn't exist. C<remove>returns a remainder/multiplicty pair. C<root> returns the nth root, andC<roote> returns a root/bool pair, the bool indicating whether the root isexact. C<sqrtrem> returns a root/remainder pair.C<clrbit> and C<setbit> expect a variable which they can modify,it doesn't make sense to pass a literal constant. Only the given variableis modified, if other variables are referencing the same mpz object then anew copy is made of it. If the variable isn't an mpz it will be coerced toone. For instance, use GMP::Mpz qw(setbit); setbit (123, 0); # wrong, don't pass a constant $a = mpz(6); $b = $a; setbit ($a, 0); # $a becomes 7, $b stays at 6C<scan0> and C<scan1> return ~0 if no 0 or 1 bit respectively is found.=head2 GMP::MpqThis class provides rationals with arbitrary precision numerators anddenominators. A new mpq can be constructed with C<mpq>. The initial valuecan be an integer, float, string, mpz, mpq or mpf, or a pair of integers ormpz's. No precision is lost when converting a float or mpf, the exact valueis retained. use GMP::Mpq qw(:all); $a = mpq(); # zero $b = mpq(0.5); # gives 1/2 $b = mpq(14); # integer 14 $b = mpq(3,4); # fraction 3/4 $b = mpq("7/12"); # fraction 7/12 $b = mpq("0xFF/0x100"); # fraction 255/256When a fraction is given, it should be in the canonical form specified inthe GMP manual, which is denominator positive, no common factors, and zeroalways represented as 0/1. If not then C<canonicalize> can be called to putit in that form. For example, use GMP::Mpq qw(:all); $q = mpq(21,15); # eek! common factor 3 canonicalize($q); # get rid of itThe following overloaded operators are available, and correspondingassignment forms like C<+=>,=over 4=item+ - * / E<lt>E<lt> E<gt>E<gt> ** ! E<lt> E<lt>= == != E<gt> E<gt>=E<lt>=E<gt> abs not=backThe following functions are available,=over 4=itemden, inv, num=backC<inv> calculates 1/q, as per the corresponding GMP function. C<num> andC<den> return an mpz copy of the numerator or denominator respectively. Inthe future C<num> and C<den> might give lvalues so the original mpq can bemodified through them, but this is not done currently.=head2 GMP::MpfThis class provides arbitrary precision floating point numbers. Themantissa is an arbitrary user-selected precision and the exponent is a fixedsize (one machine word).A new mpf can be constructed with C<mpf>. The initial value can be aninteger, float, string, mpz, mpq or mpf. The second argument specifies thedesired precision in bits, or if omitted then the default precision is used. use GMP::Mpf qw(:all); $a = mpf(); # zero $b = mpf(-7.5); # default precision $c = mpf(1.5, 500); # 500 bits precision $d = mpf("1.0000000000000001");The following overloaded operators are available, with the correspondingassignment forms like C<+=>,=over 4=item+ - * / E<lt>E<lt> E<gt>E<gt> ** ! E<lt> E<lt>= == != E<gt> E<gt>=E<lt>=E<gt> abs not sqrt=backThe following functions are available, behaving the same as thecorresponding GMP mpf functions,=over 4=itemceil, floor, get_default_prec, get_prec, mpf_eq, set_default_prec, set_prec,trunc=back
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -