Final edits and version bump for 2.1.0a1.

This commit is contained in:
Case Van Horsen 2017-11-05 20:41:06 -08:00
parent f9493ac806
commit b42966aa54
10 changed files with 58 additions and 1078 deletions

View file

@ -84,6 +84,6 @@ If you get a "permission denied" error message, you may need to use:
Installing gmpy2 on Windows
---------------------------
Please see msys2_build.txt.
Please see windows_build.txt (preferred) or msys2_build.txt (alpha).

View file

@ -1,845 +0,0 @@
gmpy module -- a complete Python 2.4+ and 3.x interface for GMP/MPIR.
*Notes on history of file gmpydoc.txt*
Notes for version 0.1 (pre-alpha), first one placed on sourceforge
-- A. Martelli, aleaxit@yahoo.com, 00/11/06.
Edited for version 0.2 (still pre-alpha), bugfixes & minor
performance tweaks, 00/11/15 -- many thanks to Pearu Peterson for
his contributions re 0.1 -> 0.2!
Edited for version 0.3 (ditto) -- cleanup, exposing more mpz
functions (almost all there...!), large performance-tweaks via
caching (tx to PP for the inspiration!), some unit-tests -- **NEED
MANY MORE TESTS FOR 0.4**!!! -- 00/11/18.
Small edits for version 0.4 (ditto) -- just a couple more
functions, and minor error-corrections -- 11/24. (Added
docstrings in 0.4; would be nice to build a doc of some kind
automatically from ONE place...).
Edited for version 0.5 (ditto) -- documented the new functionality
(mostly mpq; also: random, jacobi/legendre/ kronecker), minor
cleanups & corrections -- 11/30.
Editing for versions 0.6 (12/07), 0.7 (12/16), 0.8 (12/26):
documented new functionalities, and performed minor cleanups
& corrections, each time.
Very minor editing for version 0.9 (2001/01/25).
Minor editing for version 0.9b (2002/02/28).
Minor editing for version 0.9c (2002/03/05).
Minor editing for version 1.0 (2003/08/08).
Minor editing for version 1.01 (2005/11/12);
maintainer's preferred email changed to aleaxit@gmail.com .
Minor editing for version 1.02 (2007/02/19).
Minor editing for version 1.03 (2008/06/22).
Minor editing for version 1.04 (2008/10/16).
Minor editing for version 1.10 (2009/10/18)
*Acknowledgments*
gmpy 0.1 was based on previous versions of gmpmodule.c (for
earlier Python and GMP releases) by AMK and Niels Möller (only
removed feature: conditional possibility to substitute this
implementation in place of Python's built-in longs; lots and lots
of added features).
Special thanks are due to Pearu Peterson for his MANY important
inputs on design aspects, performance tweak suggestions, and bug
discoveries.
Thanks also to Keith Briggs for his precious feedback, and to Tim
Peters, Fredrik Lundh, "and a cast of thousands" (posters to
c.l.py and, in some few cases, gmpy's sf discussion groups) for their
suggestions. Furthermore, thanks to Case Van Horsen, who provided
the Windows binary installers for gmpy 1.01.
Chip Turner and Daniel Lord helped with the changes leading to version
1.02, so, thanks to them as well!
Case Van Horsen has done almost all of the work leading to version 1.03,
so, SUPER thanks!-) (He's also pointed out the issues requiring the
enhancements in 1.04, mainly rich comparisons, and done other changes
leading from 1.03 to 1.04).
*Installation and testing*
Pre-requisites: Python 2.4+ or 3.x, and recent versions of GMP
(http://gmplib.org) or MPIR (http://www.mpir.org). gmpy has been tested
with GMP version 4.2+ and MPIR 1.2+.
To build gmpy from sources, get the sources from svn (or a sources
zipfile, such as gmpy-1.10.zip) from http://code.google.com/p/gmpy/source.
Place the source code into a new, dedicated directory, cd to that
directory (from any shell on Unix/Linux, or from Terminal on Mac OS X),
and run:
python setup.py install
The DistUtils that come with Python take over and build and
install the gmpy module for you (you may need to use 'sudo' or
'su' appropriately to actually perform the installation, depending
on the permissions you're using on Python's site-packages).
Detailed instructions for building on Windows are included in
"windows_build.txt" and "win_x64_sdk_build.txt". "windows_build.txt"
describes the build process using Mingw32 and MSYS and was used to
build the 32-bit Windows binaries. "win_x64_sdk_build.txt" describes
the build process using the Microsoft Platform SDK and was used to
build the 64-bit Windows binaries. The MPIR library offers better
support for Windows and is recommended.
The file "mac_build.txt" contains detailed instructions for compiling
GMP and GMPY on MacOSX (or getting GMP via mactools/darwintools).
The sources zipfile also contains this file (gmpydoc.txt), an
example C source file for a separate module that uses the C-API of
gmpy to interoperate with it, a copy of the index.html for the
gmpy sourceforge site, and python scripts that exemplify, show the
performance of, and test, some functionality of the gmpy module.
To test the installation, cd to the directory where you unpacked
the gmpy sources, and run, at the command prompt:
cd test
(Note: use "cd test3" if you are using Python 3.x.)
and then, at the next prompt:
python gmpy_test.py
Expected output is something like (details may differ!):
"""
Unit tests for gmpy 1.02 release candidate
on Python 2.5 (r25:51918, Sep 19 2006, 08:49:13)
[GCC 4.0.1 (Apple Computer, Inc. build 5341)]
Testing gmpy 1.02 (GMP 4.2), default caching (20, 20, -2..11)
gmpy_test_cvr 270 tests, 0 failures
gmpy_test_rnd 26 tests, 0 failures
gmpy_test_mpf 155 tests, 0 failures
gmpy_test_mpq 264 tests, 0 failures
gmpy_test_mpz 386 tests, 0 failures
gmpy_test_dec 16 tests, 0 failures
7 items had no tests:
[[ snip snip ]]
31 items passed all tests:
[[ snip snip ]]
1117 tests in 38 items.
1117 passed and 0 failed.
Test passed.
"""
Should you wish to test some specific portion, please note that
each of the various modules listed at the start can also be run
independently, if so desired:
python gmpy_test_mpq.py
python gmpy_test_mpz.py
and so on, expecting output analogous to the above example. You
may also run, for example,
python gmpy_test_mpq.py -v
to get very verbose and detailed output. However, in any case,
the key issue is the 'Test passed' line at the end of each run!
*PLEASE* report any failures to gmpy's maintainers, with all details you
can supply on your machine, on your OS, and on your installation of GMP
4, gmpy 1.04, Python 2.3, 2.4, 2.5, or 2.6, and any other relevant issue
(your C/C++ compiler & libraries, &c). *THANKS* in advance -- bug
reporting and feedback is your key contribution to the gmpy project!
(Reports of any _successful_ installations will also be welcome, if it's
accompanied by enough details -- again, THANKS in advance!). The best
way to report bugs (including unit-test failures) is via the Google Code
issue tracker.
*General notes on gmpy*
Note that the mpfr() type from the MPFR library replaced GMP's mpf()
type in gmpy2.
gmpy exposes to Python three types of numbers that are implemented
in GMP and MPIR:
mpz unlimited-precision integers
mpq unlimited-precision rationals
mpf extended-precision floats
See GMP documentation for general descriptions of them!
GNU MP Home Page: http://gmplib.org
The MPIR documentation is available from:
MPIR Home Page: http://www.mpir.org
Licensing: gmpy is licensed under LGPL v2 or later. MPIR is also
licensed under LGPL v2 or later. GMP converted to LGPL v3 beginning
with version 4.2.2. IANAL, but, summarizing, this means: other
_libraries_ that are derived from gmpy must also be distributed
under the LPGL (or full-GPL), as must any modifications/additions to
gmpy; but, no such restriction applies on code that just _uses_ these
modules/libraries (such gmpy-using code may thus be licensed in whatever
way is desired).
Warranty: NONE -- as usual for open-source software (see the
detailed disclaimers in GMP's license)!
*gmpy.mpz -- unlimited-precision integral numbers*
gmpy.mpz objects have the full arithmetic abilities of Python
longs (in the future, there may also be mutable versions of them
[for performance], but NOT yet).
Specifically, arithmetic operators + and - (unary and binary), *,
/ (truncating), %, **, bitwise operators such as &, |, ^, <<, >>,
~, and builtin Python functions such as divmod and pow, all work
as expected on mpz objects (basically, the same way as on builtin
Python longs, except that the speed can be quite different -- from
'a bit slower' for some things, up to much faster for others [such
as multiplication of huge numbers]).
Mixed-operand arithmetic is supported: the other operand (which
must be a number of some kind) is coerced to a gmpy.mpz, unless
it's of a floating type, in which case both operands are coerced into
a gmpy.mpf object. Instances of the decimal.Decimal class are coerced
into gmpy.mpf also. Instances of the fractions.Fraction class are
coerced int gmpy.mpq.
An mpz object can be built by passing to the gmpy.mpz constructor
function any Python built-in, non-complex number, another mpz
(this *shares* object identity, does *not* copy it -- which should
be indifferent, since such objects are in any case immutable), a
mpq or mpf (which gets truncated, as also a Python float does), or
a string (representing the number in base 10).
gmpy.mpz can also be called with TWO arguments: the first one a
string representing the number in some base N, the second one, the
integer N. N can be between 2 and 36, or it can be 256, which
implies that the string is the _portable binary gmpy
representation_ of the mpz (as produced by method .binary() of mpz
objects, and function gmpy.binary() of the module).
An N of 0 is also accepted, and means the string is interpreted as
decimal, unless it starts with 0x (then, hexadecimal) or 0 (then,
octal). When N=16 a starting a leading '0x' is also accepted, but
not required; leading 0's are always accepted and ignored (they do
NOT mean the rest is taken as octal!) if the base N is explicitly
given as a Python int, or if it's omitted (and defaults to 10).
*NOTE* that the trailing-L in a Python's "long" string
representation is NOT accepted in the string argument to
gmpy.mpz()!
(Please note that all from-string transformations are performed by
GMP or MPIR, and thus may follow slightly different conventions from
normal Python ones).
An mpz object can be transformed into a Python number by passing
it as the argument of a call to Python's built-in number types
(int, long, float, complex); it can also be formatted as an octal
or hex string with Python built-in functions oct and hex.
mpz objects also support the hash built-in function, and can thus
be used as dictionary keys; for any Python int or long N,
hash(mpz(n)) and hash(n) are equal.
Other operations on mpz objects are all exposed as functions of
module gmpy, and some, also, as methods of mpz objects. Unless
otherwise noted, arguments to the following gmpy module functions
are coerced to mpz (unless already of mpz type), and values
returned from either functions or methods are also of mpz type.
gmpy.binary(x) or x.binary(): returns a portable binary
representation (base-256 little endian) of an mpz object, suitable
for saving into a file (or db, whatever) -- this string can later
be passed as the first argument to function gmpy.mpz (with a
second argument with value 256) to reconstruct a copy of the
original mpz object. *NOTE*: the binary format used by gmpy
release 0.7 and later is not compatible with that of 0.6 and
earlier, as the latter, as a design limitation, could not
represent any mpz number that was < 0.
gmpy.digits(x[,base]) or x.digits([base]): returns a string
representing x in the given base (between 2 and 36, defaulting to
10 if omitted or zero); a leading '-' will be present if x<0, but
no leading '+' if x>=0. If base is 8 or 16, a decoration of a
leading '0' (or, respectively, '0x') is present (after the '-'
sign, if the number is negative).
gmpy.numdigits(x[,base]) or x.numdigits([base]): returns an
approximation to the number of digits for x in the given base
(result is either exact [guaranteed if base is a power or 2] or 1
more than actual length; space for a "sign", or leading
decorations of '0' or '0x', is NOT considered). Base must be
between 2 and 36, defaulting to 10 if omitted or zero.
gmpy.sign(x) or x.sign(): -1, 0, or 1, depending on whether x is
negative, zero, or positive.
gmpy.divm(a, b, M): x such that b*x == a modulo M (will raise a
ZeroDivisionError exception if no such x exists).
gmpy.fac(x): factorial of x (takes O(x) time; x must be an
ordinary Python non-negative integer!)
gmpy.fib(x): x-th Fibonacci number (takes O(x) time; x must be an
ordinary Python non-negative integer).
gmpy.gcd(a,b): greatest common divisor of a and b (an mpz, >= 0).
gmpy.gcdext(a, b): a tuple (g,s,t) such that
g==gmpy.gcd(a,b) and g == a*s + b*t
(g, s and t are all mpz).
gmpy.lcm(a,b): least common multiple of a and b (an mpz, >= 0).
gmpy.is_square(x) or x.is_square(): 1 iff x is a perfect square,
else 0 (returns Python int).
gmpy.is_power(x) or x.is_power(): 1 iff x is a perfect power
(i.e., there exist a, b such that a**b==x and b>1), else 0
(returns Python int).
gmpy.is_prime(x [, count]) or x.is_prime([count]): 2 if x is
_certainly_ prime, 1 if x is _probably_ prime, 0 if x is
_certainly_ composite; count defaults to 25 (probability of
non-primality, if is_prime returns 1, is guaranteed to be no
higher than 1 in 2**count). Returns Python int.
NOTE: GMP believes negative numbers can be primes, and gmpy just
reflects this stance (cfr discussion at
http://www.utm.edu/research/primes/notes/faq/negative_primes.html)
gmpy.next_prime(x) or x.next_prime(): returns mpz that is the
lowest prime > x; *probabilistic* algorithm for
prime-determination (see is_prime).
gmpy.sqrt(x) or x.sqrt(): integer square-root of non negative
number (truncating, unless is_square(x)).
gmpy.sqrtrem(x) or x.sqrtrem(): tuple (s,t) such that
s==gmpy.sqrt(x) and x==s*s+t. (s and t are mpz, >= 0).
gmpy.root(x,n) or x.root(n): tuple (s,b) such that s is the
truncated nth-root of x, b!=0 if s is the _exact_ root (i.e.
x==s**n); n must be an ordinary Python int, >0. (s is an mpz, b a
Python int).
gmpy.bincoef(x, N) or x.bincoef(N): binomial coefficient "x over
N"; N must be an ordinary Python int, >=0! (x may be < 0 , see
Knuth vol 1, sect 1.2.6, part G). [Also known as: gmpy.comb(x, N)
or x.comb(N), since the binomial coefficient is also the number of
different combinations of x objects taken N at a time, with
ordering ignored].
gmpy.remove(x, f) or x.remove(f): "remove factors": returns a
two-element tuple (y,m), where y, an mpz, is x without any factor
of f, and m (an ordinary Python int) is the multiplicity of f in x
(e.g.: m==0 and y==x unless x%f==0; and in any case, it's ensured
that x==y*(f**m) and that y%f!=0).
gmpy.invert(x, m) or x.invert(m): modulo-inverse; returns an y
such that x*y mod m = 1, if one exists, else 0 (returns an mpz in
either case).
gmpy.lowbits(x, n) or x.lowbits(n): returns the n lowest bits of x
(n must be an ordinary Python int, >0; returns an mpz, >= 0).
Note that x<0 is assumed to be in 2's complement notation (i.e.,
"extended on the left" with infinite 1-bits); so, for example, for
any n>0, gmpy.lowbits(-1,n) returns an mpz>0 with the lowest n
bits set to 1, i.e., (2**n)-1.
gmpy.setbit(x, n, v) or x.setbit(n, v), n being a bitindex (0 and
up, ordinary Python int) and v an int value (0 or 1, default 1):
returns a copy of x with bit n set to v (mpz's are not mutable --
yet...!). [Any value v != 0 is equivalent to v=1, i.e., the bit
is 'set'; so, for example, gmpy.setbit(0,n,-4) for any n>=0
returns an mpz worth 2**n].
gmp.getbit(x, n) or x.getbit(n), n being a bitindex (0 and up,
ordinary Python int): returns an int which is 0 or 1, same as the
value of bit n of x. (See note on gmpy.lowbits for x<0).
gmpy.scan0(x [, n]) or x.scan0([n]): returns the bit index of the
next 0-bit starting at bit n (default 0); n must be an ordinary
Python int, >=0; returns a Python int (-1 if there is no such
bit-index, which can only happen for an x<0, which notionally is
extended with infinite 1-bits).
gmpy.scan1(x [, n]) or x.scan1([n]): returns the bit index of the
next 1-bit starting at bit n (default 0); n must be an ordinary
Python int, >=0; returns a Python int (-1 if there is no such
bit-index, which can only happen for an x>=0, which notionally is
extended with infinite 0-bits).
gmpy.popcount(x) or x.popcount(): returns the "population count"
(number of bits set to 1) of x; note that this is 'infinite' for
x<0 (-1 is then returned). Returns a Python int.
gmpy.hamdist(x,y) or x.hamdist(y): returns the Hamming-distance
|x,y| if both >=0 or both < 0 (returns -1 if one but not both are
<0) (the hamming distance is defined as: the number of
bit-positions in which the two numbers differ). Returns a Python
int. Same as gmpy.popcount(x^y).
gmpy._copy(x) or x._copy(): provide a separate copy of x (only
relevant for future mutability of mpz... currently useless!).
gmpy.divexact(x,y): returns the quotient of x divided by y. It uses
a faster division algorithm but requires that the remainder is 0.
It will return garbage if the remainder is not 0! (New in 1.04.)
*gmpy module-level setting functions*
[NOTE: the overall architecture of these functions is due to be
reworked sooner or later, NOT backwards-compatibly].
gmpy.set_debug(flag): turns on/off debugging output from the gmpy
module (returns previous setting). [Only of interest to
develop/debug gmpy itself!] Argument must be an ordinary Python
int: debug is set on if flag!=0, off if flag==0. Returns a Python
int (0 or 1, the _previous_ setting).
gmpy.set_tagoff(flag): turns off/on the 'gmpy.' prefix to the
"tag" that repr() places around the string-representation of gmpy
objects (returns a Python int, 0 or 1, the previous setting).
gmpy. get_zcache(), set_zcache(N), get_zconst(), set_zconst(N,M),
get_qcache(), set_qcache(N)...: *internal tweaks/experimental
stuff*, please don't use them unless you've read the C sources and
understand what they do! Not further documented here (docstrings
for these functions in gmpy may give a little more detail).
*gmpy.mpq -- unlimited-precision rational numbers*
gmpy.mpq objects have a subset of the arithmetic abilities of
Python floats (in the future, mutable versions will also be
supplied, but, NOT YET!), but represent arbitrary rational numbers
with no loss of precision whatsoever.
[Note, in particular, that raising-to-power works only without a
modulo, and, if the exponent is a fraction with a denominator D
(or gets converted to one), the base must be an exact D-th power,
or the operation fails raising a ValueError exception].
Mixed-operand arithmetic is supported: the other operand is
coerced to a gmpy.mpq. NOTE: the % operator and the divmod
built-in function are NOT supported. mpq objects also support the
hash built-in function, and can thus be used as dictionary keys;
for any Python int or long N, hash(mpq(n)) and hash(n) are equal.
A mpq object has a _numerator_ and a _denominator_; they can be
obtained by calling on an mpq object the methods .numer() and
.denom() -- each method has no arguments and returns an mpz (the
denominator will always be >0; the numerator can be any; also, the
numerator and denominator never have any common factors; mpq
corresponding to integers, including 0, always have a denominator
of exactly 1).
An mpq is built by passing to the gmpy.mpq constructor function
any Python number, another mpq (this *shares* object identity,
does *not* copy it), a mpf or mpz, or a string (representing the
number in base 10). [If an mpf or float argument is passed, the
mpq is built from it with an 'optimal' approach based on a
Stern-Brocot tree; see also the f2q method of mpf objects, and
gmpy.f2q module-level function, which differ from explicit
mpq-construction in that it can return an mpz if the mpq's
denominator would be 1].
gmpy.mpq can also be called with TWO arguments: the first one a
string representing the number in base N, the second one, the
integer N. N can be between 2 and 36, or, it can be 256, which
implies that the string is the _portable binary gmpy
representation_ of the mpq (as produced by method .binary() of mpq
objects, and function gmpy.qbinary() of the module).
gmpy.mpq is typically called with a string that contains a '/'
character: the digits before it will then be taken as the
numerator, those after it, as the denominator (the resulting
number is normalized: denominator>0, no common factors). A
ZeroDivisionError is raised if the denominator thus supplied is
zero; a ValueError, if the string is otherwise invalid (e.g., '/3'
or '3/'). Hex and octal representations are supported if the base
N is given as 0; see above gmpy.mpz; for example,
mpq('0x13/011',0) is the same as mpq(19,9).
gmpy.mpq can also be called with two number arguments: the first
one is taken as the numerator, the second one as the denominator
(the resulting number is normalized: denominator>0, no common
factors). A ZeroDivisionError is raised if the denominator thus
supplied is zero.
Other operations on mpq objects are all exposed as functions of
modules gmpy, and some, also, as methods of mpq objects:
gmpy.qbinary(x) or x.binary(): returns a portable binary
representation of any mpq object.
gmpy.qsign(x) or x.sign(): -1, 0, or 1, depending on whether x is
negative, zero, or positive.
gmpy.qdiv(x[,y]) or x.qdiv([y]), which is _also_ supplied as a
method on mpz and mpf objects (which are implicitly converted to
mpq's in this case): return x/y (or just x, if y is absent), as an
mpz if possible (==if a resulting mpq would have a denominator of
1), else as an mpq (with a denominator > 1). The functions are
optimized, so that, if x is an mpz and y is absent or 1, or if x
is an mpq with a denom>1 and y is absent or 1, then the same
object-identity as x is returned, so that the operation is very
fast. In other words, gmpy.qdiv only ever takes substantial time
if it DOES have an important job to perform, and can thus be
called rather freely, even in loops, to 'normalize' numeric
results.
Specifically, please note that, for an x that is an mpq, x.qdiv()
returns either x, if x.denom()==1, or else the same mpz as
x.numer() would return; if x is an mpz, x.qdiv() returns x (so it
can be used polymorphically on an x that can be either, without
any performance hit).
*gmpy.mpf -- variable-precision floating numbers*
gmpy.mpf objects have a subset of the arithmetic abilities of
Python floats (in the future, mutable versions will also be
supplied, but, NOT YET!).
Mixed-operand arithmetic is supported: the other operand is
coerced to a gmpy.mpf, except that, if the other operand is an
mpq, then both are coerced to mpq. NOTE: trigonometric and
exponential functionalities on mpf objects are NOT currently
supported [GMP 3.1.1 had none; waiting to expose the MPFR
extensions to GMP.] mpf objects also support the hash built-in
function, and can thus be used as dictionary keys; for any Python
float X, hash(mpf(x)) and hash(x) are equal.
Each mpf object has a _precision_ -- a number of bits of precision
to which values are stored in it. The precision of all newly
generated mpf's is at least that set at module level via module
function gmpy.set_minprec(n); a specific mpf's precision can be
set to >= n bits by x.setprec(n); it can be queried (the exact
current number of bits of precision is returned) by x.getprec() or
gmpy.getprec(x). The granularity of precision of current MPF's is
rough; exact precision setting is one of MPFR's enhancements. To
get the actual precision that was _requested_ for a given mpf
object, x.getrprec() and gmpy.getrprec(x) are also supplied -- the
value returned from getprec will always be greater than, or equal
to, the one returned from getrprec.
** The following behavior is in new in gmpy 1.04. **
GMP only guarantees that the precision of a result is greater than
or equal to the requested precision. But comparisons would use all
the bits computed, regardless of whether they are accurate. This
leads to situations where mpf('1.1') * mpf('1') != mpf('1.1').
Beginning with gmpy 1.04, the results of all mpf calculations are
rounded to the requested precision.
Note: GMP uses radix 2**32 (or 2**64) arithmetic and rounding is
done on those boundaries. Let's assume we request 53 bits of
precision on a 32-bit system. GMP rounds the requested precision
up to 64 bits and then allocates three 32-bit words to store the
mantissa. GMP also allocates one additional 32-bit word to simplify
their internal operations. The additional word may or may not be
present on any particular result. So in our scenario, GMP can return
a mantissa with anywhere between 65 and 128 bits. The presence of
the additional word caused the strange behavior with comparisons.
If the additional word is present, the mantissa is rounded and the
additional word is set to 0 so the effective precision is between
65 and 96 bits.
** End new section. **
An mpf is built by passing to the gmpy.mpf constructor function
any Python built-in number, another mpf (this *shares* object
identity, does *not* copy it -- unless specific precision is
requested for the resulting mpf, see later), a mpq or mpz, or a
string (representing the number in base 10, possibly with decimal
point and/or exponent).
If gmpy.mpf is called with a float argument, the exact steps used
in conversion depend on the setting of module level option fcoform
(set by gmpy.set_fcoform()).
If fcoform is None, the float number is converted 'exactly' to an
mpf (which often leaves spurious trailing bits from literals). If
fcoform is a string, it's used as the format (left operand of %)
in a formatting operation (with the float being transformed as the
right operand), and the resulting intermediate string is the one
that actually gets transformed to mpf (this normally gives good
results with formats somewhere between '%.12e' and '%.16e',
depending on the actual precision of the float being transformed).
fcoform also applies to _implicit_ conversions of float to mpf, as
invoked for mixed-mode arithmetic or when gmpy functions expecting
an mpf argument are called with a float argument (a string could
not be passed _explicitly_ here -- an explicit mpz() around it
would be needed -- but it's OK if a float gets _implicitly_
converted-to-mpf-via-string in these cases, through the fcoform
mechanism).
An optional second argument can always be supplied to gmpy.mpf,
whether the first argument is a number or a string; if supplied,
it must be a Python int, >=0. If absent or 0, the precision of
the mpf that is generated is determined by default depending on
the input argument (in many cases, it's the number of significant
bits in machine-floats; e.g., 53 on machines using IEEE 64-bit
floating point). If the second argument is supplied and > 0, it's
used as the requested-precision for the resulting mpf, ignoring
the bits-of-precision held or implied by the first argument.
Note, that if x is an mpf with n bits of precision, gmpy.mpf(x,m)
will be able to return the same object identity as x if, and only
if, m==n; else, a new mpf object of the requested precision will
be generated.
Note that, in arithmetic operations, the bits of precision of the
result are generally set to the _lowest_ number of
bits-of-precision of all the operands involved.
gmpy.mpf can also be called with *3* arguments: the first one a
string representing the number in base N, the second one the bits
of precision requested (or 0 to accept the default determination
of the bits), the third one, the integer N. N can be between 2
and 36, or, it can be 256, which implies that the string is the
_portable binary gmpy representation_ of the mpf (as produced by
method .binary() of mpf objects, and function gmpy.fbinary() of
the module). (Hex and octal decorations are *not* supported here;
an N of 0 is totally equivalent to one of 10).
Note that therefore, if a reasonable fcoform is set, two
constructor calls such as
gmpy.mpf(3.4)
and
gmpy.mpf('3.4')
will produce the same mpf object, although the second way is
faster (and does not depend on the module-level fcoform setting)
and recommended as preferable to the first one.
Other operations on mpf objects are all exposed as functions of
modules gmpy, and some, also, as methods of mpf objects:
gmpy.fbinary(x) or x.binary(): returns a portable binary
representation of any mpf object.
gmpy.fdigits(x[,args...]) or x.digits([args]): returns a string
representing x. Arguments (must currently be passed positionally,
if at all -- keywords NOT accepted!) are...:
base: number-base (between 2 and 36), default 10
digits: how many digits are requested (default 0,
"all of them" within x's precision; fewer than
requested may be obtained, if fewer available)
minexp: minimum exponent for which the number is
still to be formatted in integer.fraction form
(it's formatted as fraction-exponent form if
exponent is lower than minexp), default 0
maxexp: maximum exponent for which the number is
still to be formatted in integer.fraction form
(it's formatted as fraction-exponent form if
exponent is higher than maxexp), default -1
option: bitmask argument, default 0 (no options)
Note that, by default, the formatting is in fraction-and-exponent
form:
[<sign>]<digit>.<digits><marker><signed exponent>
sign is '-' if x is negative, omitted if x>=0
<marker> is 'e' for base<=10, otherwise '@'
the signed exponent (sign omitted if exponent>=0) is always
expressed in base 10, whatever the base used for the significand's
digits.
If option's bit 1 is set, the whole result string is enclosed
between "gmpy.mpf('" at the start and "')" at the end, so it can
be subject to eval to recover an approximation of the original
number (depending on the settings of gmpy.set_tagoff(), the
starting tag may actually be shortened to just "mpf('"). The
precision, in bits, is also output in this case, just before the
')', separated from the "first argument to gmpy.mpf" by a comma
character (it is the same number as returned by .getrprec).
If option's bit 2 is set, then minexp, maxexp, and option's bit 1,
are ignored: the result is a tuple of 2 objects: first, a string
made up of all the digits (and maybe a leading - sign) and nothing
else; second, an integer that is the exponent to use. This can be
used by Python code that wants finer-grained control on resulting
string format.
gmp.reldiff(x,y) or x.reldiff(y): returns the relative difference
between x and y, a non-negative mpf roughly equal to
abs(x-y)/((abs(x)+abs(y))/2).
gmpy._fcopy(x) or x._copy(): provide a separate copy of x (only
relevant for future mutability of mpf..!).
gmpy.fsign(x) or x.sign(): -1, 0, or 1, depending on whether x is
negative, zero, or positive.
gmpy.f2q(x) or x.f2q(): like gmpy.mpq(x), but, like qdiv, will
return an mpz (instead of, as normally, an mpq), if the mpq's
denominator would be 1.
gmpy.fsqrt(x) or x.sqrt(): square-root of non negative number x.
gmpy.set_fcoform([x]): sets or resets the format with which to
build the intermediate-string to be used for float->mpf
conversion. If x is None, or is absent, then the format is reset,
and such conversions proceed 'directly'. If x is a Python int, it
must be between 1 and 30, and is used as the number of digits in
the format string '%.<x>e' (for example, set_fcoform(12) will set
the format string for float-conversion to '%.12e'). Else, x must
be a Python string usable as:
x%f
to format a float object f in some suitable way. set_fcoform also
returns the previous setting of this option, None or a string.
(See also the paragraph above about the float->mpf conversion
mechanics, which gives more details about the way in which this
format string is used by gmpy).
*Experimental: function gmpy.rand*
Support for these random number generation functions was removed
in gmpy2. A new API will be introduced.
Since gmpy 0.5, the linear congruential random number generator of
GMP is exposed via gmpy (with some modest added-value
functionality) through function gmpy.rand. A couple of options were
added in 0.6. This will be refactored into separate functions in
some future release.
Its first parameter is a string 'opt' (4-characters, lowercase)
which determines the exact functionality; it normally has a second
parameter 'arg' (which is optional for most values of 'opt') and
may return either None or a significant value (an mpz, except for
opt='floa', when an mpf is returned).
gmpy.rand('init')
Initialize the random-generator state (this
is _implicitly_ called by other options of
gmpy.rand, if needed, but should be explicitly
called) to ensure 32 bits' randomness per
each generation ('throw'). Returns None.
gmpy.rand('init', arg)
ditto, but ensure 'arg' bits of randomness
(arg being an int between 1 and 128). This
tweaks the linear congruential parameters
according to the number of needed bits (it
may be faster to generate just the needed
number of 'good' bits). Returns None.
gmpy.rand('qual')
returns the current 'quality of random
numbers' (the arg value passed to 'init',
with a default of 32), or 0 if random
number generation is not initialized yet.
[ignores arg, if present]
gmpy.rand('seed', arg)
set the current random-seed to 'arg', an
mpz (or coerced to mpz). Returns None.
gmpy.rand('seed')
set the current random-seed 'randomly' in
its turn (uses C-level function 'rand()').
Returns None.
gmpy.rand('save')
returns the current random-seed (an mpz)
so that it can be saved (e.g. for program
checkpointing) and later restored via
a gmpy.rand('seed', x) call.
[ignores arg, if present]
gmpy.rand('next')
returns a uniformly distributed random
number in the range 0:2**31 (note that
the UPPER end is EXCLUDED) and advances
the random-number generation by 1 step.
(Basically, returns '31 random bits', if
the current quality of the generator is
at least 31; for lower-quality generators,
upper bits tend to be "better" than less
significant ones).
gmpy.rand('next',arg)
returns a uniformly distributed random
number in the range 0:arg (note that
the UPPER end is EXCLUDED) and advances
the random-number generation by 1 step.
Value returned is integral (mpz).
gmpy.rand('floa',arg)
returns a uniformly distributed random
number in the range 0:1 (note that
the UPPER end is EXCLUDED), with arg
meaningful bits (default, if arg is 0,
is current 'quality'), and advances the
random-number generation by 1 step.
Value returned is floating-point (mpf).
gmpy.rand('floa')
returns a uniformly distributed random
number in the range 0:1 (note that
the UPPER end is EXCLUDED), with as many
meaningful bits as the current 'quality',
and advances random-number generation by 1
step. Value returned is floating-point (mpf).
gmpy.rand('shuf',arg)
randomly shuffles mutable-sequence 'arg'
(normally a list), in a way that ensures
all permutations are equally likely. It
advances random-number generation by
len(arg)-1 steps. Returns None.
*Experimental: the callbacks-facility*
The "callback" facilities were removed in gmpy 1.10. The documentation
is left as-is for historical reference.
Since gmpy 0.8, gmpy exposes 'callback' facilities to help
client-code customize the handling of what, in pure-gmpy, would be
error-cases. This is mostly intended for the use of Pearu
Peterson's PySymbolic package, and is not currently documented
(nor tested) in great detail for general use. You are welcome to
contact gmpy's maintainer directly (and/or study gmpy's C
sources:-) if you think you may have use for this facility, or are
interested in doing something similar in other C modules for
Python use -- it IS an interesting and reasonably novel approach.
To summarize: with gmpy.set_callback(name, callable), client-code
may set a Python callable as a callback for gmpy in a set of
situations determined by the string 'name'. For example,
gmpy.set_callback('ZD', myfun)
sets 'myfun' as the callback that gmpy is to use in
'zero-division' situations. When gmpy is about to raise a
ZeroDivision error, it checks if the 'ZD' callback is set; if so,
then, instead of raising the exception itself, it delegates
everything to the callback in question, passing it the name of the
gmpy function involved, the arguments it was called with, and the
error-string gmpy would use if it did raise the error. It's up to
the callback to either raise a ZeroDivision itself, OR return some
special object to map this situation -- for example, PySymbolic
may return an 'infinity' object and suppress the error.
Basically, this works around Python's (excellent!) choice to adopt
the terminating-model rather than the restartable one for
exception handling, in a few cases of specific interest to numeric
computation that's being used in a symbolic setting.
Most callbacks are module-global, with one specific exception.
When any gmpy function or method is trying to convert arguments to
gmpy objects (mpz, mpq, mpf), and a conversion fails, all argument
objects are examined, looking for a method called '__gmpy__' in
any of them.
If one is found, then, rather than raising an error to indicate
the conversion failure, that method is called as a 'localized
callback' as above. This lets other, non-gmpy objects participate
in gmpy computations (if they're willing to handle all cases
involving them!): Python does much of this via __coerce__ etc, and
this localized-callback facility does the rest for named
module-functions and methods, where normal coercion would not
apply.

View file

@ -1,198 +0,0 @@
<HTML>
<HEAD>
<TITLE>Welcome to General Multiprecision PYthon
</TITLE>
<!--
<LINK rel="stylesheet"
href="http://sourceforge.net/sourceforge.css"
type="text/css">
-->
<STYLE>
body { margin-left: 30; margin-right: 30; }
</STYLE>
</HEAD>
<BODY>
<FONT SIZE=-1>
Last updated on: 2008, June 22;
for GMPY release: 1.04
<A href="http://code.google.com/p/gmpy/">
<IMG src="http://code.google.com/images/code_sm.png"
width="88" height="31" border="0" alt="Go to Google Code gmpy page"></A>
<br>
</FONT>
<H1>GMPY Project goals and strategies</H1>
The General Multiprecision PYthon project (GMPY) focuses on
Python-usable modules providing multiprecision arithmetic
functionality to Python programmers. The project mission
includes both C and C++ Python-modules (for speed) and pure
Python modules (for flexibility and convenience); it
potentially includes integral, rational and floating-point
arithmetic in any base. Only cross-platform functionality
is of interest, at least for now.
<P>
As there are many good existing free C and C++ libraries
that address these issues, it is expected that most of the
work of the GMPY project will involve wrapping, and exposing
to Python, exactly these existing libraries (possibly with
additional "convenience" wrappers written in Python itself).
For starters, we've focused on the popular (and excellent)
GNU Multiple Precision library,
<A HREF="http://gmplib.org/">GMP</A>,
exposing its functionality through module <b>gmpy</b>.
<H1>The GMPY Module</H1>
<P>
Python modules older than GMPY exposes a subset of the integral-MP
(MPZ) functionality of earlier releases of the GMP library. The
first GMPY goal (currently nearly reached) was to develop the gmpy
module into a complete exposure of MPZ, MPF (floating-point), and
MPQ (rational) functionality of current GMP (release 4), as well
as auxiliary functionality such as random number generation, with
full support for current Python releases (2.3 and up) and the
Python 'distutils' (and also support for a "C API" allowing some
level of interoperation with other C-written extension modules for
Python).
<p>
<b>Note</b>: the module's ability to be used as a "drop-in
replacement" for Python's own implementation of <i>long</i>s,
to rebuild Python from sources in a version using GMP, was a
characteristic of the gmp-module we started from, but is
<b>not</b> a target of the gmpy project, and we have no plans
to support it.
<P>
This first GMPY
module is called <b>gmpy</b>, just like the whole project.
<P>
The extended MP floating-point facilities of
<A HREF="http://www.loria.fr/projets/mpfr/">MPFR</A>
will later also be considered for inclusion in gmpy (either within
the same module, or as a further, separate add-on module).
[[ Rooting for MPFR to be merged with GMP so we can avoid some
awkwardness (but seeing no movement on this front so far) ]].
<H2>Mutability... but <u>not</u> for now</H2>
Early tests have shown that supporting Python 2's "in-place
operation" functionality (by making MPZ, MPF and MPQ Python objects
<b>mutable</b>) would offer a substantial performance boost.
<p>
Despite this, widespread feeling among Python cognoscenti appears
to be against exposing such "mutable numbers". As a consequence,
our current aim is for a first release of GMPY without mutability,
to be followed at some later time by one which will also fully
support in-place-mutable versions of number objects (as well as
the default immutable ones), but only when explicitly and
deliberately requested by a user (who can then be presumed to know
what he or she is doing). Meanwhile, caching strategies are used
to ameliorate performance issues, and appear to be reasonably
worthwhile (so far, only MPZ and MPQ objects are subject to this
caching).
<p>
We've tended to solve other debatable design issues in a similar
vein, i.e., by trying to work "like Python's built-in numbers" when
there was a choice and two or more alternatives made sense.
<H1>Project Status and near-future plans</H1>
The gmpy module's current release (latest current release
as of 2008/10/16: 1.04) is available for download in both
source and Windows-binary form, and Mac-binary form too.
gmpy 1.04 exposes all of the mpz, mpq
and mpf functionality that was already available in GMP 3.1, and
most of the random-number generation functionality (there are no
current plans to extend gmpy to expose other such functionality,
although the currently experimental way in which it is architected
is subject to possible future changes).
<p>
On most platforms, you will need to separately procure and install
the GMP library itself to be able to build and use GMPY. Note that
4.0.1 or better is needed; take care: some Linux releases come bundled
with <strong>older</strong> GMP versions, such as GMP 3, and you may
have to install the latest GMP version instead -- beware also of
/usr/lib vs /usr/local/lib issues.
<p>
Please read the file "windows_build.txt" for detailed instructions on
compiling GMP and GMPY using the freely available MinGW tools.
<p>
[[ OLD: The exception to this need is under (32-bit) Windows, where
binary-accompanied releases are the norm, and builds of GMP usable
with MS VC++ 6 (the main C compiler used for Python on this platform)
are traditionally hard to come by.
<p>
We started the GMPY project using a VC++ port of GMP.LIB "just found on
the net", and later a port by Jorgen Lundman, but are currently relying
on other volunteers to build Windows binaries since we don't have any
Windows machine any more. <a
href="http://www.cs.nyu.edu/exact/core/gmp/">This site</a> does appear
to offer all needed files and instructions for Windows developers who
want to re-build the gmpy module from sources; the gmpy project itself
just supplies a separate 'binary module' package is supplied, containing
only the pre-built GMPY.PYD, for those who do <b>not</b> want to
re-build from sources. ]]
<p>
<b>Do</b> note, however, that <b>all</b> gmpy users should download the
gmpy source-package as well, as currently that is the one including
<b>gmpy</b> documentation and unit-tests!
<H2>Currently-open issues</h2>
<p>
A still-weakish point is with the output-formatting of mpf numbers;
sometimes, this formatting ends up providing a few more digits than
a given number's accuracy would actually warrant (a few noise digits
after a long string of trailing '0' or '9' digits), particularly when
the mpf number is built from a Python float -- the accuracy situation
is quite a bit better when the mpf number is built from a <b>string</b>.
<p>
Because of this, since release 0.6, gmpy introduced an optional
'floating-conversion format string' module-level setting: if present,
float-&gt;mpf conversion goes through an intermediate formatted
string (by default, it still proceeds directly, at least for now);
this does ameliorate things a bit, as does the better tracking done
(since 0.6, with further enhancements in 0.7) of the 'requested'
precision for an mpf (as opposed to the precision the underlying GMP
actually 'assigns' to it); but the issue cannot yet be considered fully
solved, and may well still need some design changes in the output
formatting functionality.
<p>
Unit tests are not considered a weak point any more; the over 1000
unit-tests now being run provide a decent cover of 93+% SLOC for gmpy.c,
up from 72% in 0.7. The non-covered SLOCs (about 150 of gmpy.c's
current 2311 executable lines out of 6205 total)
are mostly disaster-tests to handle out-of-memory
situations, a smattering of 'defensive
programming' cases (to handle situations that 'should never happen,
but'...) and some cases of the new experimental 'callbacks' facility
(mostly provided for the specific use of PySymbolic, and intended to be
tested by that package). We'll have to do better, eventually (presumably with
some mocking approach e.g. to simulate out-of-memory situations), but, for now,
this can be considered OK.
<p>
In the attempt to make gmpy as useful as can be for both stand-alone
use, and also in the context of PySymbolic, a tad too many design
decisions have been delayed/postponed by introducing module-level
flags, letting us 'have it both ways' in the current
gmpy 1.04; this has produced a somewhat unwieldy mix of module-level
flag-setting and call-back functions. This whole area's architecture
will neet to be revisited, including other such design-decisions yet.
<H2>Near-future plans</h2>
Future releases may have changes including: re-architecting the
module-level setting functions; more elegantly formatted documentation;
more timing-measurement scripts and usage-examples. Some of the
currently experimental 'callbacks' will also be removed, having been
proven unnecessary. All relevant GMP 4 functionality will be exposed.
<p>
No predictions on timing, though. gmpy 1.04 meets all current needs
of the main author, so his motivation to work more on it is low:-).
So, don't hold your breath (pitching in and helping it happen, on the
other hand, _might_ be advisable, and will surely yield results:-).
<p>
<A HREF="http://code.google.com/p/gmpy/">Project page on
code.google.com</A>
<A href="http://code.google.com/p/gmpy/">
<IMG src="http://code.google.com/images/code_sm.png"
width="88" height="31" border="0" alt="Go to Google Code gmpy page"></A>
</BODY>
</HTML>

View file

@ -50,7 +50,7 @@ copyright = u'2012, 2013, 2014, 2017 Case Van Horsen'
# The short X.Y version.
version = '2.1'
# The full version, including alpha/beta/rc tags.
release = '2.1.0a0'
release = '2.1.0a1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View file

@ -1,7 +1,7 @@
Changes for gmpy2 releases
==========================
Changes in gmpy2 2.1.0a0
Changes in gmpy2 2.1.0a1
------------------------
* Thread-safe contexts are now supported. Properly integrating thread-safe

View file

@ -47,7 +47,7 @@ Enhancements in gmpy2 2.1
The most significant changes in gmpy2 2.1 are:
Changes in gmpy2 2.1.0a0
Changes in gmpy2 2.1.0a1
------------------------
* Thread-safe contexts are now supported. Properly integrating thread-safe
@ -66,13 +66,11 @@ Changes in gmpy2 2.1.0a0
* In previous versions of gmpy2, *gmpy2.mpz* was a factory function that
returned an *mpz* instance. *gmpy2.mpz* is now an actual type. The same
is true for the other gmpy2 types.
* If a Python object has an __mpz__ method, it will be called bye *mpz()* to
* If a Python object has an __mpz__ method, it will be called by *mpz()* to
allow an unrecognized type to be converted to an mpz instance. The same is
true for the other gmpy2 types.
* Support for Cython via the addition of a C-API and a gmpy2.pxd file.
Please see the detailed change list
Installation
============
@ -82,10 +80,9 @@ wheel format.
Installing gmpy2 on Windows
---------------------------
Pre-compiled versions of gmpy2 are available at `Downloads
<http://code.google.com/p/gmpy/downloads/list>`_ . Please
select the installer that corresponds to the version of Python installed on
your computer. Note that either a 32 or 64-bit version of Python can be
Pre-compiled versions of gmpy2 are available at `https://pypi.python.org/pypi/gmpy2`.
Please select the installer that corresponds to the version of Python installed
on your computer. Note that either a 32 or 64-bit version of Python can be
installed on a 64-bit version of Windows. If you get an error message
stating that Python could not be found in the registry, you have the wrong
version of the gmpy2 installer.
@ -200,8 +197,11 @@ Options for setup.py
Force the use of GMP instead of MPIR. MPIR is the default library on Windows
operating systems.
**--prefix=<...>**
Specify the directory prefix where GMP/MPIR, MPFR, and MPC are located. For
example, **--prefix=/opt/local** instructs setup.py to search /opt/local/include
for header files and /opt/local/lib for libraries.
**--shared=<...>**
Add the specified directory prefix to the beginning of the list of
directories that are searched for GMP, MPFR, and MPC shared libraries.
**--static=<...>**
Create a statically linked library using libraries from the specified path,
or from the operating system's default library location if no path is specified

View file

@ -295,12 +295,12 @@ gmpy2_ext = Extension('gmpy2',
define_macros = defines)
setup(name = "gmpy2",
version = "2.1.0a0",
version = "2.1.0a1",
author = "Case Van Horsen",
author_email = "casevh@gmail.com",
license = "LGPL-3.0+",
url = "https://github.com/aleaxit/gmpy",
description = "gmpy2 interface to GMP/MPIR, MPFR, and MPC for Python 2.7 and 3.4+",
description = "gmpy2 interface to GMP/MPIR, MPFR, and MPC for Python 2.6+ and 3.4+",
data_files = [('', ['src/gmpy2.pxd']), ('gmpy2', ['src/gmpy2.h'])],
classifiers = [
'Development Status :: 3 - Alpha',
@ -313,6 +313,7 @@ setup(name = "gmpy2",
'Operating System :: POSIX',
'Programming Language :: C',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',

View file

@ -418,7 +418,7 @@
/* The following global strings are used by gmpy_misc.c. */
char gmpy_version[] = "2.1.0a0";
char gmpy_version[] = "2.1.0a1";
char gmpy_license[] = "\
The GMPY2 source code is licensed under LGPL 3 or later. The supported \
@ -812,7 +812,7 @@ static PyMethodDef Pygmpy_methods [] =
};
static char _gmpy_docs[] =
"gmpy2 2.1.0a0 - General Multiple-precision arithmetic for Python\n"
"gmpy2 2.1.0a1 - General Multiple-precision arithmetic for Python\n"
"\n"
"gmpy2 supports several multiple-precision libraries. Integer and\n"
"rational arithmetic is provided by either the GMP or MPIR libraries.\n"

View file

@ -4,13 +4,13 @@ Miscellaneous Functions
>>> import gmpy2
>>> from gmpy2 import mpz
>>> gmpy2.version()
'2.1.0a0'
'2.1.0a1'
>>> gmpy2.mp_limbsize() in (32,64)
True
>>> gmpy2.mp_version().split()[0] in ['GMP', 'MPIR']
True
>>> check_gmp = gmpy2.mp_version().startswith('GMP') and '5.0.0' <= gmpy2.mp_version().split()[1]
>>> check_mpir = gmpy2.mp_version().startswith('MPIR') and '2.4.0' <= gmpy2.mp_version().split()[1]
>>> check_mpir = gmpy2.mp_version().startswith('MPIR') and '3.0.0' <= gmpy2.mp_version().split()[1]
>>> check_gmp or check_mpir
True
>>> gmpy2.mpfr_version() and gmpy2.mpfr_version().startswith('MPFR')

View file

@ -1,9 +1,13 @@
Assumptions
===========
The build files for MPIR, MPFR, and MPC only support VS 2010. However, if
VS 2008 is also installed, the "Platform Toolset" setting can be used to select
a specific compiler: v100 = VS 2010, v90 = VS 2008.
The solution files for MPIR, MPFR, and MPC support VS 2015/2017.
However, if VS 2008 and/or VS 2010 is installed, the "Platform
Toolset" setting can be used to select a specific compiler:
- v90 = VS 2008, Python 2.6 and 2.7
- v100 = VS 2010, Python 3.3 and 3.4
- v140 = VS 2015, Python 3.5, 3.6, and 3.7
- v141 = VS 2017
Assumes MPIR is placed in c:\src\mpir. (No version number.)
Assumes MPFR is placed in c:\src\mpfr. (No version number.)
@ -11,6 +15,20 @@ Assumes MPC is placed in c:\src\mpc. (No version number.)
Assumes gmpy2 is placed in c:\src\gmpy2. (No version number.)
Assumes vsyasm is installed.
Compatibility note for vsyasm
=============================
VS 2015/2017 change the platform identifier for 32-bit builds from
"win32" to "Win32". To work around the issue with vsyasm v1.3.0, edit
the "vsyasm.props" file. After the following line:
<CommandLineTemplate>"$(YasmPath)"vsyasm.exe -Xvc -f $(Platform) [AllOptions] [AdditionalOptions] [Inputs] </CommandLineOptions>
add this line:
<CommandLineTemplate Condition="'$(Platform)' == 'Win32'">"$(YasmPath)"vsyasm.exe -Xvc -f win32 [AllOptions] [AdditionalOptions] [Inputs] </CommandLineOptions>
Compiling MPIR
==============
@ -145,17 +163,21 @@ xcopy /y c:\src\mpc\lib\x64\Release\*.lib c:\src\64\vs2015\lib\
Compile gmpy2
=============
c:\32\Python26\python.exe setup.py build_ext -f -Ddir=c:\src\32\vs2008 bdist_wininst
c:\32\Python27\python.exe setup.py build_ext -f -Ddir=c:\src\32\vs2008 bdist_wininst
c:\32\Python34\python.exe setup.py build_ext -f -Ddir=c:\src\32\vs2010 bdist_wininst
c:\32\Python35\python.exe setup.py build_ext -f -Ddir=c:\src\32\vs2015 bdist_wininst
c:\32\Python36\python.exe setup.py build_ext -f -Ddir=c:\src\32\vs2015 bdist_wininst
c:\32\Python26\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2008 bdist_wininst
c:\32\Python27\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2008 bdist_wininst
c:\32\Python33\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2010 bdist_wininst
c:\32\Python34\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2010 bdist_wininst
c:\32\Python35\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2015 bdist_wininst
c:\32\Python36\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2015 bdist_wininst
c:\32\Python37\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2015 bdist_wininst
c:\64\Python26\python.exe setup.py build_ext -f -Ddir=c:\src\64\vs2008 bdist_wininst
c:\64\Python27\python.exe setup.py build_ext -f -Ddir=c:\src\64\vs2008 bdist_wininst
c:\64\Python34\python.exe setup.py build_ext -f -Ddir=c:\src\64\vs2010 bdist_wininst
c:\64\Python35\python.exe setup.py build_ext -f -Ddir=c:\src\64\vs2015 bdist_wininst
c:\64\Python36\python.exe setup.py build_ext -f -Ddir=c:\src\64\vs2015 bdist_wininst
c:\64\Python26\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2008 bdist_wininst
c:\64\Python27\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2008 bdist_wininst
c:\64\Python33\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2010 bdist_wininst
c:\64\Python34\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2010 bdist_wininst
c:\64\Python35\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2015 bdist_wininst
c:\64\Python36\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2015 bdist_wininst
c:\64\Python37\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2015 bdist_wininst