Eli*_*sky 10
因为它是默认的整数除法.并且整数除法向无穷大舍入.看一看:
>>> -22/10
-3
>>> -22/10.0
-2.2000000000000002
Run Code Online (Sandbox Code Playgroud)
正:
>>> 22/10
2
>>> 22/10.0
2.2000000000000002
Run Code Online (Sandbox Code Playgroud)
关于浮点的看似"不准确",这是一篇很好的文章:为什么浮点计算如此不准确?
默认情况下,当两个操作数都是整数时,Python 2.x的当前版本(我不确定3.x)会为任何算术运算符提供整数结果.但是,有一种方法可以改变这种行为.
from __future__ import division
print(22/10)
Run Code Online (Sandbox Code Playgroud)
输出
2.2000000000000002
Run Code Online (Sandbox Code Playgroud)
当然,更简单的方法是简单地使其中一个操作数浮动,如前两个答案所述.
PEP 238,"改变分部操作员",我认为这些问题很好地解释了.简而言之:当Python被设计时,它采用/
整数之间的"截断"含义,因为大多数其他编程语言自1957年第一个FORTRAN编译器启动以来就做过(全大写语言名称和所有;-).(一种普遍的语言没有采用这种意义,/
用于产生浮点结果和div
截断,是Pascal).
2001年,它决定这个选择是不是最佳的(引自PEP,"这使表达期待浮动或复杂的结果容易出错预计不会整数的时候,但可能作为输入"),并切换到使用新的运营商//
来请求使用截断进行除法,并更改/
生成浮点结果的含义("true division").
您可以通过放置语句来显式请求此行为
from __future__ import division
Run Code Online (Sandbox Code Playgroud)
在模块的开头(命令行切换-Q
到python
解释器也可以控制除法的行为).对于x的所有值,缺少这样的"从未来导入"(和命令行开关使用),Python 2.x,总是使用"经典划分"(即,/
在int
s 之间截断).
然而,Python 3总是使用"真正的划分"(s /
之间int
产生a float
).
请注意一个奇怪的推论(在Python 3中)......:
>>> from fractions import Fraction
>>> Fraction(1/2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/fractions.py", line 100, in __new__
raise TypeError("argument should be a string "
TypeError: argument should be a string or a Rational instance
Run Code Online (Sandbox Code Playgroud)
因为/
产生了一个float
,它是不可接受的参数Fraction
(否则精度可能会默默地丢失).您必须使用字符串,或将分子和分母作为单独的参数传递:
>>> Fraction(1, 2)
Fraction(1, 2)
>>> Fraction('1/2')
Fraction(1, 2)
Run Code Online (Sandbox Code Playgroud)
gmpy使用一种不同的,更宽容的方法来构建mpq
s,它相当于Python 3 Fraction
...:
>>> import gmpy
>>> gmpy.mpq(1/2)
mpq(1,2)
Run Code Online (Sandbox Code Playgroud)
具体来说(参见第3168行和后面的源代码),gmpy使用Stern-Brocot树来获得浮点参数的"最佳实际近似"作为理性(当然,这可以掩盖精度的损失).