为什么python会对这些比较感到困惑?



如果我在Python 3.8.6中运行这段代码,我会得到输出False:

(((3980 - 91 + 1)/(3980)) * ((1 / 3980)**(91 - 1))) > (((3981 - 91 + 1)/(3981)) * ((1 / 3981)**(91 - 1)))

然而,如果我在WolframAlpha中运行这个,它返回True

我猜这是由于浮动不精确造成的。但为什么偏偏发生在这里呢?在我为下面的函数测试的1200万种sz组合中,这种情况只发生了两次。z = 91withs = 3980andz = 92withs = 3457.

(((s - z + 1)/(s)) * ((1 / s)**(z - 1))) > ((((s+1) - z + 1)/(s+1)) * ((1 / (s+1))**(z - 1)))

同样,在你的解释器中试试这些:

  1. (((3458 - 92 + 1)/(3458)) * ((1 / 3458)**(92 - 1))) > (((3459 - 92 + 1)/(3459)) * ((1 / 3459)**(92 - 1)))
  2. (((3457 - 92 + 1)/(3457)) * ((1 / 3457)**(92 - 1))) > (((3458 - 92 + 1)/(3458)) * ((1 / 3458)**(92 - 1)))
  3. (((3456 - 92 + 1)/(3456)) * ((1 / 3456)**(92 - 1))) > (((3457 - 92 + 1)/(3457)) * ((1 / 3457)**(92 - 1)))

他们给出了这些结果:

  1. True
  2. False
  3. True

为什么模式True False True只发生在这些输入上?保持z不变,其他s的值都不返回False

舍入错误。如果你想知道确切的信息,请阅读IEEE 754规范。你的数字太小了,它们在非正常范围内,在你的例子中有5-10位的精度。正常范围内的浮点数精度为53位。


如果您使用float.hex()查看这两个值,它会显示它们的精确二进制表示:

>>> (((3980 - 91 + 1)/(3980)) * ((1 / 3980)**(91 - 1))).hex()
'0x0.0p+0'
>>> (((3981 - 91 + 1)/(3981)) * ((1 / 3981)**(91 - 1))).hex()
'0x0.0p+0'

它们在IEEE 754float64精度下都很小,它们都四舍五入为零。如果事实上最后一项真的小:

>>> ((1/3981)**89).hex()
'0x0.0000000000327p-1022'

Mark Tolonen回答了你的问题,如果你需要更精确,使用分数:

>>> from fractions import Fraction
>>> (Fraction(3980 - 91 + 1, 3980) * Fraction(1, 3980) ** (91 - 1)) > (Fraction(3981 - 91 + 1, 3981) * Fraction(1, 3981) ** (91 - 1))
True

相关内容

  • 没有找到相关文章

最新更新