2001-03-15 23:19:37 -05:00
|
|
|
|
PEP: 238
|
|
|
|
|
Title: Non-integer Division
|
|
|
|
|
Version: $Revision$
|
2001-07-25 12:51:27 -04:00
|
|
|
|
Author: pep@zadka.site.co.il (Moshe Zadka), guido@python.org (Guido van Rossum)
|
2001-03-15 23:19:37 -05:00
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
|
|
|
|
Created: 11-Mar-2001
|
|
|
|
|
Python-Version: 2.2
|
2001-03-16 11:02:24 -05:00
|
|
|
|
Post-History: 16-Mar-2001
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
|
|
|
|
|
Dividing integers currently returns the floor of the quantities.
|
|
|
|
|
This behavior is known as integer division, and is similar to what
|
|
|
|
|
C and FORTRAN do. This has the useful property that all
|
|
|
|
|
operations on integers return integers, but it does tend to put a
|
|
|
|
|
hump in the learning curve when new programmers are surprised that
|
|
|
|
|
|
|
|
|
|
1/2 == 0
|
|
|
|
|
|
|
|
|
|
This proposal shows a way to change this while keeping backward
|
|
|
|
|
compatibility issues in mind.
|
|
|
|
|
|
2001-07-25 12:53:19 -04:00
|
|
|
|
NOTE: in the light of recent discussions in the newsgroup, the
|
|
|
|
|
motivation in this PEP (and details) need to be extended. I'll do
|
|
|
|
|
that ASAP.
|
|
|
|
|
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
|
|
|
|
|
The behavior of integer division is a major stumbling block found
|
|
|
|
|
in user testing of Python. This manages to trip up new
|
|
|
|
|
programmers regularly and even causes the experienced programmer
|
|
|
|
|
to make the occasional mistake. The workarounds, like explicitly
|
|
|
|
|
coercing one of the operands to float or use a non-integer
|
|
|
|
|
literal, are very non-intuitive and lower the readability of the
|
|
|
|
|
program.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Operator
|
|
|
|
|
|
|
|
|
|
A `//' operator which will be introduced, which will call the
|
|
|
|
|
nb_intdivide or __intdiv__ slots. This operator will be
|
|
|
|
|
implemented in all the Python numeric types, and will have the
|
|
|
|
|
semantics of
|
|
|
|
|
|
|
|
|
|
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
|
2001-07-25 12:51:27 -04:00
|
|
|
|
will be of that type too. In the current Python 2.2 implementation,
|
|
|
|
|
this is implemented via the BINARY_INTDIVIDE opcode, and currently
|
|
|
|
|
does the right thing only for ints and longs (and other extension types
|
|
|
|
|
which behave like integers).
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Changing the Semantics of the / Operator
|
|
|
|
|
|
|
|
|
|
The nb_divide slot on integers (and long integers, if these are a
|
2001-07-05 15:09:19 -04:00
|
|
|
|
separate type, but see PEP 237 [1]) will issue a warning when given
|
2001-03-15 23:19:37 -05:00
|
|
|
|
integers a and b such that
|
|
|
|
|
|
|
|
|
|
a % b != 0
|
|
|
|
|
|
|
|
|
|
The warning will be off by default in the 2.2 release, and on by
|
|
|
|
|
default for in the next Python release, and will stay in effect
|
|
|
|
|
for 24 months. The next Python release after 24 months, it will
|
|
|
|
|
implement
|
|
|
|
|
|
|
|
|
|
(a/b) * b = a (more or less)
|
|
|
|
|
|
|
|
|
|
The type of a/b will be either a float or a rational, depending on
|
2001-07-25 12:51:27 -04:00
|
|
|
|
other PEPs[2, 3]. However, the result will be integral in all case
|
|
|
|
|
the division has no remainder. This will not implemented in Python 2.2.
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__future__
|
|
|
|
|
|
2001-07-25 12:51:27 -04:00
|
|
|
|
See PEP 236[4] for the __future__ specific rules.
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-25 12:51:27 -04:00
|
|
|
|
If "from __future__ import division" is present in the
|
|
|
|
|
module, until the IntType nb_divide is changed, the "/" operator
|
|
|
|
|
is compiled to add 0.0 to the divisor before doing the division.
|
|
|
|
|
This is not exactly the same as what will happen in the future,
|
|
|
|
|
since in the future, the result will be integral when it can.
|
|
|
|
|
This is done via the BINARY_FLOATDIVIDE opcode.
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-25 12:51:27 -04:00
|
|
|
|
In Python 2.2, unless the __future__ statement is present,
|
|
|
|
|
the '/' operator is compiled to DIVISION opcode, which is the
|
|
|
|
|
same
|
|
|
|
|
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-25 12:51:27 -04:00
|
|
|
|
C API
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-25 12:51:27 -04:00
|
|
|
|
There are four new C-level functions. PyNumber_IntDivide and
|
|
|
|
|
PyNumber_FloatDivide correspond to the // operator and
|
|
|
|
|
the / operator with __future__ statement, respectively.
|
|
|
|
|
PyNumber_InPlaceIntDivide and PyNumber_InPlaceIntDivide correspond
|
|
|
|
|
to the //= operator and to the /= operator with __future__ statement
|
|
|
|
|
respectively. Please refer to the discussion of the operator
|
|
|
|
|
for specification of these functions' behavior.
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-22 11:03:26 -04:00
|
|
|
|
|
|
|
|
|
FAQ
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
Should the // operator be renamed to "div"?
|
|
|
|
|
|
2001-07-22 11:03:26 -04:00
|
|
|
|
No. There are problems with new keywords.
|
|
|
|
|
|
2001-03-19 14:36:46 -05:00
|
|
|
|
Should the // be made into a function called "div"?
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-22 11:03:26 -04:00
|
|
|
|
No. People expect to be able to write math expressions directly
|
|
|
|
|
in Python.
|
|
|
|
|
|
2001-07-22 00:24:09 -04:00
|
|
|
|
|
|
|
|
|
Implementation
|
|
|
|
|
|
|
|
|
|
A mostly-complete implementation (not exactly following the above
|
|
|
|
|
spec, but close enough except for the lack of a warning for
|
|
|
|
|
truncated results from old division) is available from the
|
2001-07-25 12:51:27 -04:00
|
|
|
|
SourceForge patch manager[5]
|
2001-07-22 00:24:09 -04:00
|
|
|
|
|
|
|
|
|
|
2001-03-15 23:19:37 -05:00
|
|
|
|
References
|
|
|
|
|
|
|
|
|
|
[1] PEP 237, Unifying Long Integers and Integers, Zadka,
|
2001-07-05 15:09:19 -04:00
|
|
|
|
http://www.python.org/peps/pep-0237.html
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
[2] PEP 239, Adding a Rational Type to Python, Zadka,
|
2001-07-05 15:09:19 -04:00
|
|
|
|
http://www.python.org/peps/pep-0239.html
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
[3] PEP 240, Adding a Rational Literal to Python, Zadka,
|
2001-07-05 15:09:19 -04:00
|
|
|
|
http://www.python.org/peps/pep-0240.html
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
2001-07-25 12:51:27 -04:00
|
|
|
|
[4] PEP 236, Back to the __future__, Peters,
|
|
|
|
|
http://www.python.org/peps/pep-0236.html
|
|
|
|
|
|
|
|
|
|
[5] Patch 443474, from __future__ import division
|
|
|
|
|
http://sourceforge.net/tracker/index.php?func=detail&aid=443474&group_id=5470&atid=305470
|
|
|
|
|
|
2001-03-15 23:19:37 -05:00
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
End:
|