131 lines
4.5 KiB
Plaintext
131 lines
4.5 KiB
Plaintext
PEP: 239
|
||
Title: Adding a Rational Type to Python
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: Christopher A. Craig <python-pep@ccraig.org>,
|
||
Moshe Zadka <moshez@zadka.site.co.il>
|
||
Status: Rejected
|
||
Type: Standards Track
|
||
Created: 11-Mar-2001
|
||
Python-Version: 2.2
|
||
Post-History: 16-Mar-2001
|
||
|
||
|
||
Abstract
|
||
|
||
Python has no numeric type with the semantics of an unboundedly
|
||
precise rational number. This proposal explains the semantics of
|
||
such a type, and suggests builtin functions and literals to
|
||
support such a type. This PEP suggests no literals for rational
|
||
numbers; that is left for another PEP[1].
|
||
|
||
BDFL Pronouncement
|
||
|
||
This PEP is rejected. The needs outlined in the rationale section
|
||
have been addressed to some extent by the acceptance of PEP 327
|
||
for decimal arithmetic. Guido also noted, "Rational arithmetic
|
||
was the default 'exact' arithmetic in ABC and it did not work out as
|
||
expected". See the python-dev discussion on 17 June 2005.
|
||
|
||
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 behavior which is
|
||
less surprising to newbies. Though many Python implementations of
|
||
rational numbers have been written, none of these exist in the
|
||
core, or are documented in any way. This has made them much less
|
||
accessible to people who are less Python-savvy.
|
||
|
||
|
||
RationalType
|
||
|
||
There will be a new numeric type added called RationalType. Its
|
||
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 and
|
||
.denominator. The language definition will promise that
|
||
|
||
r.denominator * r == r.numerator
|
||
|
||
that the GCD of the numerator and the denominator is 1 and that
|
||
the denominator is 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
|
||
|
||
|
||
Open Issues
|
||
|
||
- Maybe the type should be called rat instead of rational.
|
||
Somebody proposed that we have "abstract" pure mathematical
|
||
types named complex, real, rational, integer, and "concrete"
|
||
representation types with names like float, rat, long, int.
|
||
|
||
- Should a rational number with an integer value be allowed as a
|
||
sequence index? For example, should s[5/3 - 2/3] be equivalent
|
||
to s[1]?
|
||
|
||
- Should shift and mask operators be allowed for rational numbers?
|
||
For rational numbers with integer values?
|
||
|
||
- Marcin 'Qrczak' Kowalczyk summarized the arguments for and
|
||
against unifying ints with rationals nicely on c.l.py:
|
||
|
||
Arguments for unifying ints with rationals:
|
||
|
||
- Since 2 == 2/1 and maybe str(2/1) == '2', it reduces surprises
|
||
where objects seem equal but behave differently.
|
||
|
||
- / can be freely used for integer division when I *know* that
|
||
there is no remainder (if I am wrong and there is a remainder,
|
||
there will probably be some exception later).
|
||
|
||
Arguments against:
|
||
|
||
- When I use the result of / as a sequence index, it's usually
|
||
an error which should not be hidden by making the program
|
||
working for some data, since it will break for other data.
|
||
|
||
- (this assumes that after unification int and rational would be
|
||
different types:) Types should rarely depend on values. It's
|
||
easier to reason when the type of a variable is known: I know
|
||
how I can use it. I can determine that something is an int and
|
||
expect that other objects used in this place will be ints too.
|
||
|
||
- (this assumes the same type for them:) Int is a good type in
|
||
itself, not to be mixed with rationals. The fact that
|
||
something is an integer should be expressible as a statement
|
||
about its type. Many operations require ints and don't accept
|
||
rationals. It's natural to think about them as about different
|
||
types.
|
||
|
||
|
||
References
|
||
|
||
[1] PEP 240, Adding a Rational Literal to Python, Zadka,
|
||
http://www.python.org/dev/peps/pep-0240/
|
||
|
||
|
||
Copyright
|
||
|
||
This document has been placed in the public domain.
|
||
|
||
|
||
|
||
Local Variables:
|
||
mode: indented-text
|
||
indent-tabs-mode: nil
|
||
End:
|