Python等于浮点除法

时间:2017-10-23 03:06:07

标签: python

使用Python 3,以下内容如何返回True

a = 2/3
b = 4/6
print(a == b)

我有一个算法需要排序一个数字列表,每个数字都是x / y形式,其中x和y是整数。 (y!= 0)。

我担心分裂的数值精度会导致上述情况的不稳定性和任意排序。 This being an example of relevant comments.但是,根据示例和更大的整数,它似乎不是一个问题。

Python是否从b的分子和分母中删除公因子2,并保留a和b不仅仅是浮点数的信息?

3 个答案:

答案 0 :(得分:4)

Python遵循IEEE 754浮点规范。*(64位)IEEE浮点数基本上是基数2 scientific notation的一种形式,细分如下:

  • 符号的一位(正面或负面)
  • 53位用于尾数或有效数,包括隐含的前导数。
  • 指数为11位。

将浮点值乘以或除以2,或任何2的幂,只影响指数,而不影响尾数。**因此,它通常是一个相当“稳定”的运算,所以2 / 3应该产生与4/6相同的结果。但是,IEEE浮动仍然存在以下问题:

  • 大多数操作都不是关联的(例如,在一般情况下为(a * b) * c != a * (b * c))。
  • 更复杂的操作不需要正确舍入(但是,正如蒂姆·彼得斯指出的那样,除法当然不是“更复杂”的操作并且将被正确舍入)。***
  • 中间结果总是四舍五入为53位。

您应该准备好处理这些问题,并假设大多数数学上等效的浮点表达式不会产生相同的值。特别是在Python中,您可以使用math.isclose()来估计两个浮点数是否“足够接近”以“可能是相同的值”。

*实际上,这是一个谎言。 Python遵循C double,它几​​乎总是以某种方式遵循IEEE 754,但在充分奇特的架构上可能会偏离它。在这种情况下,C标准提供很少或没有保证,因此您必须查看您的体系结构或编译器的浮点文档。

**如果指数不上溢或下溢。如果确实如此,那么通常会分别使用适当签名的无穷大或零,或者根据体系结构和/或Python的编译方式,您可能会下载到denormal number

***“更复杂”操作的确切集合因IEEE 754 made a lot of operations optional while still demanding precision而有所不同。结果,给定的操作是符合IEEE 754还是仅符合众所周知的宽松C标准很少是显而易见的。在某些情况下,操作可能不符合任何标准。

答案 1 :(得分:3)

注意只要整数xy完全可以表示为Python浮点数,x / y在所有当前机器上都是 - 无限精确商的正确舍入值。这就是IEEE 754浮点标准所要求的,并且所有当前的机器都支持这一点。

因此,你的具体例子中的重要部分并不是b = 4/6中的分子和分母具有(特别是!)2的因子,它是(a)它们具有 some 共同因素;并且,(b)4和6都可以完全代表Python浮点数。

所以,例如,它保证

(2 * 9892837) / (3 * 9892837) == 2 / 3

也是如此。因为(2 * 9892837) / (3 * 9892837)的无限精确值与2/3的无限精确值相同,并且IEEE 754除法就好像计算了无限精确的商。并且您可以将9892837替换为任何其他非零整数,前提是产品仍然可以像Python浮动那样完全表示。

答案 2 :(得分:0)

2/3与4/6相同。 (2/3)*(2/2)= 2/2 = 1,标识元素。回答是正确的。