同步阅读进度,多语言翻译,过滤屏幕蓝光,评论分享,更多完整功能,更好读书体验,试试 阅读 ‧ 电子书库
Division: Classic, Floor, and True
You’ve seen how division works in the previous sections, so you should know that it behaves slightly differently in Python 3.0 and 2.6. In fact, there are actually three flavors of division, and two different division operators, one of which changes in 3.0:
X / Y
Classic and true division. In Python 2.6 and earlier, this operator performs classic division, truncating results for integers and keeping remainders for floating-point numbers. In Python 3.0, it performs true division, always keeping remainders regardless of types.X // Y
Floor division. Added in Python 2.2 and available in both Python 2.6 and 3.0, this operator always truncates fractional remainders down to their floor, regardless of types.True division was added to address the fact that the results of the original classic division model are dependent on operand types, and so can be difficult to anticipate in a dynamically typed language like Python. Classic division was removed in 3.0 because of this constraint—the / and // operators implement true and floor division in 3.0.
In sum:
Here are the two operators at work in 3.0 and 2.6:
C:\misc> C:\Python30\python
>>>
>>> 10 / 4 # Differs in 3.0: keeps remainder
2.5
>>> 10 // 4 # Same in 3.0: truncates remainder
2
>>> 10 / 4.0 # Same in 3.0: keeps remainder
2.5
>>> 10 // 4.0 # Same in 3.0: truncates to floor
2.0
C:\misc> C:\Python26\python
>>>
>>> 10 / 4
2
>>> 10 // 4
2
>>> 10 / 4.0
2.5
>>> 10 // 4.0
2.0
Notice that the data type of the result for // is still dependent on the operand types in 3.0: if either is a float, the result is a float; otherwise, it is an integer. Although this may seem similar to the type-dependent behavior of / in 2.X that motivated its change in 3.0, the type of the return value is much less critical than differences in the return value itself. Moreover, because // was provided in part as a backward-compatibility tool for programs that rely on truncating integer division (and this is more common than you might expect), it must return integers for integers.
Supporting either Python
Although / behavior differs in 2.6 and 3.0, you can still support both versions in your code. If your programs depend on truncating integer division, use // in both 2.6 and 3.0. If your programs require floating-point results with remainders for integers, use float to guarantee that one operand is a float around a / when run in 2.6:
X = Y // Z # Always truncates, always an int result for ints in 2.6 and 3.0
X = Y / float(Z) # Guarantees float division with remainder in either 2.6 or 3.0
Alternatively, you can enable 3.0 / division in 2.6 with a __future__ import, rather than forcing it with float conversions:
C:\misc> C:\Python26\python
>>> from __future__ import division # Enable 3.0 "/" behavior
>>> 10 / 4
2.5
>>> 10 // 4
2
Floor versus truncation
One subtlety: the // operator is generally referred to as truncating division, but it’s more accurate to refer to it as floor division—it truncates the result down to its floor, which means the closest whole number below the true result. The net effect is to round down, not strictly truncate, and this matters for negatives. You can see the difference for yourself with the Python math module (modules must be imported before you can use their contents; more on this later):
>>> import math
>>> math.floor(2.5)
2
>>> math.floor(-2.5)
-3
>>> math.trunc(2.5)
2
>>> math.trunc(-2.5)
-2
When running division operators, you only really truncate for positive results, since truncation is the same as floor; for negatives, it’s a floor result (really, they are both floor, but floor is the same as truncation for positives). Here’s the case for 3.0:
C:\misc> c:\python30\python
>>> 5 / 2, 5 / −2
(2.5, −2.5)
>>> 5 // 2, 5 // −2 # Truncates to floor: rounds to first lower integer
(2, −3) # 2.5 becomes 2, −2.5 becomes −3
>>> 5 / 2.0, 5 / −2.0
(2.5, −2.5)
>>> 5 // 2.0, 5 // −2.0 # Ditto for floats, though result is float too
(2.0, −3.0)
The 2.6 case is similar, but / results differ again:
C:\misc> c:\python26\python
>>> 5 / 2, 5 / −2 # Differs in 3.0
(2, −3)
>>> 5 // 2, 5 // −2 # This and the rest are the same in 2.6 and 3.0
(2, −3)
>>> 5 / 2.0, 5 / −2.0
(2.5, −2.5)
>>> 5 // 2.0, 5 // −2.0
(2.0, −3.0)
If you really want truncation regardless of sign, you can always run a float division result through math.trunc, regardless of Python version (also see the round built-in for related functionality):
C:\misc> c:\python30\python
>>> import math
>>> 5 / −2 # Keep remainder
−2.5
>>> 5 // −2 # Floor below result
-3
>>> math.trunc(5 / −2) # Truncate instead of floor
−2
C:\misc> c:\python26\python
>>> import math
>>> 5 / float(−2) # Remainder in 2.6
−2.5
>>> 5 / −2, 5 // −2 # Floor in 2.6
(−3, −3)
>>> math.trunc(5 / float(−2)) # Truncate in 2.6
−2
Why does truncation matter?
If you are using 3.0, here is the short story on division operators for reference:
>>> (5 / 2), (5 / 2.0), (5 / −2.0), (5 / −2) # 3.0 true division
(2.5, 2.5, −2.5, −2.5)
>>> (5 // 2), (5 // 2.0), (5 // −2.0), (5 // −2) # 3.0 floor division
(2, 2.0, −3.0, −3)
>>> (9 / 3), (9.0 / 3), (9 // 3), (9 // 3.0) # Both
(3.0, 3.0, 3, 3.0)
For 2.6 readers, division works as follows:
>>> (5 / 2), (5 / 2.0), (5 / −2.0), (5 / −2) # 2.6 classic division
(2, 2.5, −2.5, −3)
>>> (5 // 2), (5 // 2.0), (5 // −2.0), (5 // −2) # 2.6 floor division (same)
(2, 2.0, −3.0, −3)
>>> (9 / 3), (9.0 / 3), (9 // 3), (9 // 3.0) # Both
(3, 3.0, 3, 3.0)
Although results have yet to come in, it’s possible that the nontruncating behavior of / in 3.0 may break a significant number of programs. Perhaps because of a C language legacy, many programmers rely on division truncation for integers and will have to learn to use // in such contexts instead. Watch for a simple prime number while loop example in Chapter 13, and a corresponding exercise at the end of Part IV that illustrates the sort of code that may be impacted by this / change. Also stay tuned for more on the special from command used in this section; it’s discussed further in Chapter 24.
请支持我们,让我们可以支付服务器费用。
使用微信支付打赏