Python中的浮点数概念

3 投票
5 回答
1174 浏览
提问于 2025-04-15 17:22

为什么在Python中,-22除以10会得到-3呢?如果有人能给我一些提示,我会很感激。

5 个回答

5

默认情况下,当前版本的Python 2.x(我不太确定3.x的情况)在进行算术运算时,如果两个操作数都是整数,结果也会是整数。不过,有一种方法可以改变这种行为。

from __future__ import division
print(22/10)

输出结果

2.2000000000000002

当然,更简单的方法是让其中一个操作数变成浮点数,就像前面两个答案所描述的那样。

10

因为默认情况下是整数除法。整数除法的结果会向负无穷方向取整。看看这个例子:

>>> -22/10
-3
>>> -22/10.0
-2.2000000000000002

正数:

>>> 22/10
2
>>> 22/10.0
2.2000000000000002

关于浮点数计算看起来“没有精确”的问题,这里有一篇很不错的文章可以阅读: 为什么浮点数计算会这么不准确?

5

PEP 238,也就是“改变除法运算符”,把这个问题讲得很清楚。我简单说一下:在设计Python的时候,选择了对整数进行除法时用/来表示“截断”的意思,这主要是因为自从1957年第一个FORTRAN编译器推出以来,大多数其他编程语言都是这么做的(FORTRAN这个名字是全大写的哦)。有一种比较流行的语言没有这样做,它用/来得到浮点数结果,而用div来进行截断,这种语言就是Pascal。

到了2001年,人们觉得这个选择不太好(PEP中提到:“这让那些期待浮点数或复数结果的表达式在输入可能是整数时容易出错”),于是决定引入一个新的运算符//来表示截断除法,同时把/的意思改为得到浮点数结果(也就是“真实除法”)。

你可以通过在模块开头加上这条语句来明确请求这种行为:

from __future__ import division

(在命令行中使用-Q选项也可以控制除法的行为)。如果没有加上这样的“未来导入”(或者没有使用命令行选项),那么Python 2.x的所有版本都会使用“经典除法”(也就是说,/在整数之间是截断的)。

不过,Python 3总是使用“真实除法”(在整数之间用/会得到一个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

因为/会产生一个float,所以它不能作为Fraction的参数(否则可能会悄悄失去精度)。你必须使用字符串,或者把分子和分母作为单独的参数传递:

>>> Fraction(1, 2)
Fraction(1, 2)
>>> Fraction('1/2')
Fraction(1, 2)

gmpy采用了一种不同的、更宽容的方法来构建mpq,它是Python 3中Fraction的等价物……:

>>> import gmpy
>>> gmpy.mpq(1/2)
mpq(1,2)

具体来说(见源代码中的第3168行及之后的内容),gmpy使用一种叫做斯特恩-布罗科特树的方法来获取浮点参数的“最佳实际近似值”,作为一个有理数(当然,这样做可能会掩盖精度的损失)。

撰写回答