Python中的浮点概念

Cha*_*nya 3 python floating-point

为什么-22/10在python中返回-3.任何关于此的指示对我都有帮助.

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)

关于浮点的看似"不准确",这是一篇很好的文章:为什么浮点计算如此不准确?


Chi*_*chi 5

默认情况下,当两个操作数都是整数时,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)

当然,更简单的方法是简单地使其中一个操作数浮动,如前两个答案所述.


Ale*_*lli 5

PEP 238,"改变分部操作员",我认为这些问题很好地解释了.简而言之:当Python被设计时,它采用/整数之间的"截断"含义,因为大多数其他编程语言自1957年第一个FORTRAN编译器启动以来就做过(全大写语言名称和所有;-).(一种普遍的语言没有采用这种意义,/用于产生浮点结果和div截断,是Pascal).

2001年,它决定这个选择是不是最佳的(引自PEP,"这使表达期待浮动或复杂的结果容易出错预计不会整数的时候,但可能作为输入"),并切换到使用新的运营商//来请求使用截断进行除法,并更改/生成浮点结果的含义("true division").

您可以通过放置语句来显式请求此行为

from __future__ import division
Run Code Online (Sandbox Code Playgroud)

在模块的开头(命令行切换-Qpython解释器也可以控制除法的行为).对于x的所有值,缺少这样的"从未来导入"(和命令行开关使用),Python 2.x,总是使用"经典划分"(即,/ints 之间截断).

然而,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使用一种不同的,更宽容的方法来构建mpqs,它相当于Python 3 Fraction...:

>>> import gmpy
>>> gmpy.mpq(1/2)
mpq(1,2)
Run Code Online (Sandbox Code Playgroud)

具体来说(参见第3168行和后面的源代码),gmpy使用Stern-Brocot树来获得浮点参数的"最佳实际近似"作为理性(当然,这可以掩盖精度的损失).