【问题标题】:Printing a Float Beyond Its Precision打印超出其精度的浮点数
【发布时间】:2015-09-27 12:59:02
【问题描述】:

当我运行这段代码时,

print('{:.15f}'.format(123456789.55555555555555555555555555555555555555))
print('{:.25f}'.format(0.5555555555555555555555555555555555555555555555))

我得到这个输出:

123456789.555555552244186
0.5555555555555555802271783

这些多余的数字是从哪里来的(123456789.555555552244186, 0.5555555555555555802271783),为什么它们不是零?

我猜它们是由转换算法生成的,没有意义,但我想了解更多关于这方面的信息。如果转换算法将它们设为零就好了。

【问题讨论】:

  • 看看Floating point。标准 Python(又名 CPython)使用 IEEE 754 double precision 作为其 float 类型。
  • 所以,我了解浮点数的一般运作方式。但是为什么转换算法在转换的位用完时会继续转换?与小数不同,浮点数的精度有限。
  • 啊,好的。这是一个更好的问题。 :) 我不确定为什么转换例程继续进行,转换垃圾位。看起来它持续了大约 53 位数字,这很奇怪,因为 IEEE 754 双精度中有 53 个有效 。尝试将第二个数字的格式规范更改为{:.63f},您最终会看到一堆零。
  • 仅仅因为您可以键入浮点文字 0.555... 并不意味着 Python 正在准确地存储 那个 值。它将其转换为分母为 2 的幂的最接近的分数,而 that 分数的十进制扩展就是您所看到的。
  • @chepner:当然可以。但这仍然不能解释那些超出职责范围的古怪数字。 :) 例如,0.2=1/5=3/15,所以在十六进制中是 0.33333... 可以理解,它会在第 16 位之后开始产生垃圾,但是为什么转换程序还要费心再吐出垃圾 30-奇数?

标签: python floating-point formatting output precision


【解决方案1】:

当您尝试存储这些值时,实际存储的是最接近的可表示双精度二进制浮点值。这就是正在打印的内容。所以这些额外的数字实际上是有意义的——它们代表了存储的实际值。

参见Rob Kennedy's useful web page,它显示了与给定值最接近的可表示浮点数。如您所见,the closest double precision value to your first value 是:

+ 1234 56789.55555 55522 44186 40136 71875

closest double precision value to your second value 是:

+ 0.55555 55555 55555 58022 71783 25003 47867 60807 03735 35156 25

这些值与 Python 生成的值相匹配。

所以,这纯粹是可表示性的问题。更多关于浮点的参考:

【讨论】:

  • 好的,这是有道理的。我猜。 :)
  • 所以,可以肯定的是,Python 和on line converter 使用相同的转换算法。在数学方面,我仍然不清楚他们是如何得出这些额外数字的。以及为什么算法在大约 53 位数字后放弃,正如 PM 2Ring 所示。
  • 这是最接近的可表示值。 Rob 的页面和 Python 做同样的事情并不是巧合。这由标准 IEEE754 管理。您是否阅读了我给您的链接,以便您理解这意味着什么。双精度值具有 53 位二进制精度。
  • 是的,但是 53 个二进制位与 53 个十进制数字无关。还是他们?
  • 55 位十进制数字表示 最接近的双精度值到 0.1。我不认为你真的明白这一点。我建议您阅读我给您的链接。专注于数字的表示方式。
猜你喜欢
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 2021-07-25
  • 2015-02-02
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
相关资源
最近更新 更多