[Python-Dev] Adding a Rational Type to Python
Guido van Rossum
guido@digicool.com
Sun, 11 Mar 2001 18:55:03 -0500
Here's the third installment -- my response to Moshe's rational
numbers PEP.
I believe that a fourth PEP should be written as well: decimal
floating point. Maybe Tim can draft this?
> PEP: XXX
> Title: Adding a Rational Type to Python
> Version: $Revision$
> Author: pep@zadka.site.co.il (Moshe Zadka)
> Status: Draft
> Python-Version: 2.2
> Type: Standards Track
> Created: 11-Mar-2001
> Post-History:
>
>
> Abstract
>
> Python has no number type whose semantics are that of a
> unboundedly precise rational number.
But one could easily be added to the standard library, and several
implementations exist, including one in the standard distribution:
Demo/classes/Rat.py.
> This proposal explains the
> semantics of such a type, and suggests builtin functions and
> literals to support such a type. In addition, if division of
> integers would return a non-integer, it could also return a
> rational type.
It's kind of sneaky not to mention in the abstract that this should be
the default representation for numbers containing a decimal point,
replacing most use of floats!
> Rationale
>
> While sometimes slower and more memory intensive (in general,
> unboundedly so) rational arithmetic captures more closely the
> mathematical ideal of numbers, and tends to have behaviour which
> is less surprising to newbies,
This PEP definitely needs a section of arguments Pro and Con. For
Con, mention at least that rational arithmetic is much slower than
floating point, and can become *very* much slower when algorithms
aren't coded carefully. Now, naively coded algorithms often don't
work well with floats either, but there is a lot of cultural knowledge
about defensive programming with floats, which is easily accessible to
newbies -- similar information about coding with rationals is much
less easily accessible, because no mainstream languages have used
rationals before. (I suppose Common Lisp has rationals, since it has
everything, but I doubt that it uses them by default for numbers with
a decimal point.)
> RationalType
>
> This will be a numeric type. The unary operators will do the
> obvious thing. Binary operators will coerce integers and long
> integers to rationals, and rationals to floats and complexes.
>
> The following attributes will be supported: .numerator,
> .denominator. The language definition will not define other
> then that
>
> r.denominator * r == r.numerator
>
> In particular, no guarantees are made regarding the GCD or the
> sign of the denominator, even though in the proposed
> implementation, the GCD is always 1 and the denominator is
> always positive.
>
> The method r.trim(max_denominator) will return the closest
> rational s to r such that abs(s.denominator) <= max_denominator.
>
> The rational() Builtin
>
> This function will have the signature rational(n, d=1). n and d
> must both be integers, long integers or rationals. A guarantee
> is made that
>
> rational(n, d) * d == n
>
> Literals
>
> Literals conforming to the RE '\d*.\d*' will be rational numbers.
>
> Backwards Compatability
>
> The only backwards compatible issue is the type of literals
> mentioned above. The following migration is suggested:
>
> 1. from __future__ import rational_literals will cause all such
> literals to be treated as rational numbers.
> 2. Python 2.2 will have a warning, turned off by default, about
> such literals in the absence of such an __future__. The
> warning message will contain information about the __future__
> statement, and that to get floating point literals, they
> should be suffixed with "e0".
> 3. Python 2.3 will have the warning turned on by default. This
> warning will stay in place for 24 months, at which time the
> literals will be rationals and the warning will be removed.
There are also backwards compatibility issues at the C level.
Question: the time module's time() function currently returns a
float. Should it return a rational instead? This is a trick question.
> Copyright
>
> This document has been placed in the public domain.
>
>
>
> Local Variables:
> mode: indented-text
> indent-tabs-mode: nil
> End:
--Guido van Rossum (home page: http://www.python.org/~guido/)