Worked in most of the comments on the newsgroup on the previous draft.
Even changed the title.
This commit is contained in:
parent
c79f778838
commit
1edc94b63d
124
pep-0238.txt
124
pep-0238.txt
|
@ -1,23 +1,23 @@
|
|||
PEP: 238
|
||||
Title: Non-integer Division
|
||||
Title: Changing the Division Operator
|
||||
Version: $Revision$
|
||||
Author: pep@zadka.site.co.il (Moshe Zadka), guido@python.org (Guido van Rossum)
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Created: 11-Mar-2001
|
||||
Python-Version: 2.2
|
||||
Post-History: 16-Mar-2001, 26-Jul-2001
|
||||
Post-History: 16-Mar-2001, 26-Jul-2001, 27-Jul-2001
|
||||
|
||||
|
||||
Abstract
|
||||
|
||||
The current division (/) operator has an ambiguous meaning for
|
||||
numerical arguments: it returns the floor of the mathematical
|
||||
result if the arguments are ints or longs, but it returns a
|
||||
reasonable approximation of the result if the arguments are floats
|
||||
or complex. This makes expressions expecting float or complex
|
||||
results error-prone when integers are not expected but possible as
|
||||
inputs.
|
||||
result of division if the arguments are ints or longs, but it
|
||||
returns a reasonable approximation of the division result if the
|
||||
arguments are floats or complex. This makes expressions expecting
|
||||
float or complex results error-prone when integers are not
|
||||
expected but possible as inputs.
|
||||
|
||||
We propose to fix this by introducing different operators for
|
||||
different operations: x/y to return a reasonable approximation of
|
||||
|
@ -123,7 +123,7 @@ Motivation
|
|||
|
||||
Variations
|
||||
|
||||
Esthetically, x//y doesn't please everyone, and hence several
|
||||
Aesthetically, x//y doesn't please everyone, and hence several
|
||||
variations have been proposed: x div y, or div(x, y), sometimes in
|
||||
combination with x mod y or mod(x, y) as an alternative spelling
|
||||
for x%y.
|
||||
|
@ -148,7 +148,7 @@ Variations
|
|||
needed to weed out slashes occurring in comments or string
|
||||
literals.) Replacing x/y with div(x, y) would require a much
|
||||
more intelligent tool, since the extent of the expressions to
|
||||
the left and right of the / must be analized before the
|
||||
the left and right of the / must be analyzed before the
|
||||
placement of the "div(" and ")" part can be decided.
|
||||
|
||||
|
||||
|
@ -161,17 +161,16 @@ Alternatives
|
|||
c.l.py that isn't mentioned here, please mail the second author.
|
||||
|
||||
- Let / keep its classic semantics; introduce // for true
|
||||
division. This doesn't solve the problem that the classic /
|
||||
operator makes it hard to write polymorphic numeric functions
|
||||
accept int and float arguments, and still requires the use of
|
||||
x*1.0/y whenever true divisions is required.
|
||||
division. This still leaves a broken operator in the language,
|
||||
and invites to use the broken behavior. It also shuts off the
|
||||
road to a unified numeric model a la PEP 228[0].
|
||||
|
||||
- Let int division return a special "portmanteau" type that
|
||||
behaves as an integer in integer context, but like a float in a
|
||||
float context. The problem with this is that after a few
|
||||
operations, the int and the float value could be miles apart,
|
||||
it's unclear which value should be used in comparisons, and of
|
||||
course many contexts (e.g. conversion to string) don't have a
|
||||
course many contexts (like conversion to string) don't have a
|
||||
clear integer or float context.
|
||||
|
||||
- Use a directive to use specific division semantics in a module,
|
||||
|
@ -188,10 +187,10 @@ Alternatives
|
|||
- Use a directive (or some other way) to specify the Python
|
||||
version for which a specific piece of code was developed. This
|
||||
requires future Python interpreters to be able to emulate
|
||||
*exactly* every previous version of Python, and moreover to do
|
||||
so for multiple versions in the same interpreter. This is way
|
||||
too much work. A much simpler solution is to keep multiple
|
||||
interpreters installed.
|
||||
*exactly* several previous versions of Python, and moreover to
|
||||
do so for multiple versions within the same interpreter. This
|
||||
is way too much work. A much simpler solution is to keep
|
||||
multiple interpreters installed.
|
||||
|
||||
|
||||
Specification
|
||||
|
@ -240,6 +239,9 @@ Specification
|
|||
slots and call that; when that slot is NULL, they will raise an
|
||||
exception. There is no fallback to the classic divide slot.
|
||||
|
||||
In Python 3.0, the classic division semantics will be removed; the
|
||||
classic division APIs will become synonymous with true division.
|
||||
|
||||
|
||||
Command Line Option
|
||||
|
||||
|
@ -248,10 +250,10 @@ Command Line Option
|
|||
Python 2.2 but will change to "warn" in later 2.x versions. The
|
||||
"old" value means the classic division operator acts as described.
|
||||
The "warn" value means the classic division operator issues a
|
||||
warning (a DeprecatinWarning using the standard warning framework)
|
||||
when applied to ints or longs. The "new" value changes the
|
||||
default globally so that the / operator is always interpreted as
|
||||
true division. The "new" option is only intended for use in
|
||||
warning (a DeprecationWarning using the standard warning
|
||||
framework) when applied to ints or longs. The "new" value changes
|
||||
the default globally so that the / operator is always interpreted
|
||||
as true division. The "new" option is only intended for use in
|
||||
certain educational environments, where true division is required,
|
||||
but asking the students to include the future division statement
|
||||
in all their code would be a problem.
|
||||
|
@ -259,6 +261,13 @@ Command Line Option
|
|||
This option will not be supported in Python 3.0; Python 3.0 will
|
||||
always interpret / as true division.
|
||||
|
||||
(Other names have been proposed, like -Dclassic, -Dclassic-warn,
|
||||
-Dtrue, or -Dold_division etc.; these seem more verbose to me
|
||||
without much advantage. After all the term classic division is
|
||||
not used in the language at all (only in the PEP), and the term
|
||||
true division is rarely used in the language -- only in
|
||||
__truediv__.)
|
||||
|
||||
|
||||
Semantics of Floor Division
|
||||
|
||||
|
@ -267,16 +276,47 @@ Semantics of Floor Division
|
|||
|
||||
a // b == floor(a/b)
|
||||
|
||||
except that the type of a//b will be the type a and b will be
|
||||
coerced into. Specifically, if a and b are of the same type, a//b
|
||||
will be of that type too.
|
||||
except that the result type will be the common type into which a
|
||||
and b are coerced before the operation.
|
||||
|
||||
Specifically, if a and b are of the same type, a//b will be of
|
||||
that type too. If the inputs are of different types, they are
|
||||
first coerced to a common type using the same rules used for all
|
||||
other arithmetic operators.
|
||||
|
||||
In particular, if a and b are both ints or longs, the result has
|
||||
the same type and value as for classic division on these types
|
||||
(including the case of mixed input types; int//long and long//int
|
||||
will both return a long).
|
||||
|
||||
For floating point inputs, the result is a float. For example:
|
||||
|
||||
3.5//2.0 == 1.0
|
||||
|
||||
For complex numbers, // raises an exception, since float() of a
|
||||
complex number is not allowed.
|
||||
|
||||
For user-defined classes and extension types, all semantics are up
|
||||
to the implementation of the class or type.
|
||||
|
||||
|
||||
Semantics of True Division
|
||||
|
||||
True division for ints and longs will convert the arguments to
|
||||
float and then apply a float division. That is, even 2/1 will
|
||||
return a float (2.0), not an int.
|
||||
return a float (2.0), not an int. For floats and complex, it will
|
||||
be the same as classic division.
|
||||
|
||||
Note that for long arguments, true division may lose information;
|
||||
this is in the nature of true division (as long as rationals are
|
||||
not in the language). Algorithms that consciously use longs
|
||||
should consider using //.
|
||||
|
||||
If and when a rational type is added to Python (see PEP 239[2]),
|
||||
true division for ints and longs should probably return a
|
||||
rational. This avoids the problem with true division of longs
|
||||
losing information. But until then, for consistency, float is the
|
||||
only choice for true division.
|
||||
|
||||
|
||||
The Future Division Statement
|
||||
|
@ -292,13 +332,19 @@ The Future Division Statement
|
|||
|
||||
See PEP 236[4] for the general rules for future statements.
|
||||
|
||||
(It has been proposed to use a longer phrase, like "true_division"
|
||||
or "modern_division". These don't seem to add much information.)
|
||||
|
||||
|
||||
Open Issues
|
||||
|
||||
- It has been proposed to call // the quotient operator. I like
|
||||
this. I might rewrite the PEP to use this if enough people like
|
||||
it. (But isn't the assumption that this truncates towards
|
||||
zero?)
|
||||
- It has been proposed to call // the quotient operator, and the /
|
||||
operator the ratio operator. I'm not sure about this -- for
|
||||
some people quotient is just a synonym for division, and ratio
|
||||
suggests rational numbers, which is wrong. I prefer the
|
||||
terminology to be slightly awkward if that avoids unambiguity.
|
||||
Also, for some folks "quotient" suggests truncation towards
|
||||
zero, not towards infinity as "floor division" says explicitly.
|
||||
|
||||
- It has been argued that a command line option to change the
|
||||
default is evil. It can certainly be dangerous in the wrong
|
||||
|
@ -312,13 +358,25 @@ Open Issues
|
|||
|
||||
FAQ
|
||||
|
||||
Q. Why isn't true division called float division?
|
||||
|
||||
A. Because I want to keep the door open to *possibly* introducing
|
||||
rationals and making 1/2 return a rational rather than a
|
||||
float. See PEP 239[2].
|
||||
|
||||
Q. Why is there a need for __truediv__ and __itruediv__?
|
||||
|
||||
A. We don't want to make user-defined classes second-class
|
||||
citizens. Certainly not with the type/class unification going
|
||||
on.
|
||||
|
||||
Q. How do I write code that works under the classic rules as well
|
||||
as under the new rules without using // or a future division
|
||||
statement?
|
||||
|
||||
A. Use x*1.0/y for true division, divmod(x, y)[0] for int
|
||||
division. Especially the latter is best hidden inside a
|
||||
function. You may also write floor(x)/y for true division if
|
||||
function. You may also write float(x)/y for true division if
|
||||
you are sure that you don't expect complex numbers. If you
|
||||
know your integers are never negative, you can use int(x/y) --
|
||||
while the documentation of int() says that int() can round or
|
||||
|
@ -343,6 +401,10 @@ FAQ
|
|||
includes a future division statement, but that's not a general
|
||||
solution.
|
||||
|
||||
Q. Will there be conversion tools or aids?
|
||||
|
||||
A. Certainly, but these are outside the scope of the PEP.
|
||||
|
||||
Q. Why is my question not answered here?
|
||||
|
||||
A. Because we weren't aware of it. If it's been discussed on
|
||||
|
|
Loading…
Reference in New Issue