[Python-Dev] ANN: Experimental Number Types (Integer, Rational, Floats)

M.-A. Lemburg mal@lemburg.com
Thu, 19 Apr 2001 21:04:41 +0200


As you all know, Moshe Zadka has been pushing for a new rational number
type recently (at the conference) and also implemented a proof-
of-concept implementation of his rational PEP 239.

Since the GNU Multi-Precision Lib (GMP) already has all these tools
providing what people want most when it comes to numbers (precision
and speed), I thought that wrapping these as Python types would
be a good idea. I know that Alex Martelli has been working
on a similar approach, but that project (gmpy) seems to be inactive.

Anyway, even though the GMP is available for most Unix platforms
and MacOS, there was no relyable port for Windows. This was a show-
stopper for me, so I decided to port GMP to Windows, which was
harder than I though, but well, it's done now ;-)

The wrapper is called mx.Number and provides access to three
numerical types:

1. Integer(value)      -- arbitrary precision integers much like Python
                          long only faster
2. Rational(nom,denom) -- rational numbers with Integers as
                          numerator and denominator
3. Float(value[,prec]) -- floating point number with at least
                          prec bits precision

Prerequisites:
--------------

* GMP 3.1.1
  - Unix:  GMP 3.1.1 must be installed (http://www.swox.com/gmp/)
  - Windows: GMP 3.1.1 is included in the download archives for Windows

* Python 2.1

* Optional: egenix-mx-base package available from
    http://www.lemburg.com/files/python/

* The "egenix-mx-experimental" package which includes mx.Number:

  Source:
    http://www.lemburg.com/files/python/egenix-mx-experimental-0.1.0.zip
  RPM:
    http://www.lemburg.com/files/python/egenix-mx-experimental-0.1.0-1.i386-py2.1.rpm
  Windows installer:
    http://www.lemburg.com/files/python/egenix-mx-experimental-0.1.0.win32-py2.1.exe


Usage is simple:
----------------

from mx.Number import *
f = Float(3.141)
r1 = Rational(3.141)
r2 = Rational(2, 3)
i = Integer("1231231231231231231231231")

The coercion model will (someday) look like this:

                     Float
                       ^
                       |
       --------> Python float
      |                ^
      |                |
      |             Rational
      |                ^
      |                |
Python long ----->  Integer
      ^                ^
      |                |
       --------  Python integer

Complex numbers are not integrated into the picture since I
think that they should not be auto-coerced.

Some of these arrows are not implemented yet, others are not shown
(e.g. Integer(2) + "3" works as one would expect ;-).

Note that this is still a very rough version. Feedback is welcome.


Questions:
----------

* What do you think about this coercion model ? Shouldn't we
  have a PEP for this ?

* Please try out the rational type and see if it fits your
  needs -- the results are sometimes surprising (due to the
  IEEE representations of floats); I'm sure this proof of
  concept will raise a few more questions regarding the
  usefulness of switching to rationals for literals like
  1.123.

* This implementation also showed that even though the coercion
  patches have made integraton of numerical types easier, a full
  integration is still hard to achieve. Some issues:

  - string formatting cannot be "overridden" to allow formatting
    of these new types

  - there is no way of providing PyArg_ParseTuple() parser markers
    for the types

  - there is no way to bind the types to a Python literal, e.g.
    by specifying a number literal modifier which is then bound
    to the type: 1234L -> long("1234"), 1234.123F -> Float("1234.123"),
    2R / 3 -> Rational(2, 3) etc.

Comments ?
-- 
Marc-Andre Lemburg
______________________________________________________________________
Company & Consulting:                           http://www.egenix.com/
Python Pages:                           http://www.lemburg.com/python/