Python 3(使用 IEEE-754)中浮点数的 17 位十进制表示是否总是“精确”到数值精度?

Is 17-digit decimal representation of float in Python 3 (using IEEE-754) always "exact" up to numerical accuracy?

提问人:Xilexio 提问时间:6/26/2022 最后编辑:Xilexio 更新时间:6/26/2022 访问量:321

问:

对于使用 IEEE-754 浮点数的 CPython 3.10 或更高版本中从 0 到 1 的所有浮点数 r,是否符合以下情况?

float('%.17g' % r) == r

换句话说,从 0 到 1 的浮点数的 17 位十进制表示是否足够准确,足以等于它们的二进制对应物?

我的猜想是 17 位数字(但不是 16 位)是正确的,因为我还没有找到以下程序的反例:

import random

def check(precision=17):
  r = random.random()
  d = float(f'%.{precision}g' % r) - r
  if d != 0:
    print(d)

for i in range(1000000000):
  check(17)

但是,这并不涵盖所有情况,因此我正在寻找基于理论的答案。

根据答案,我正在寻找以下问题的答案:

  • 所有浮点数都是这样吗?
  • 如果猜想对 17 位数字不成立,那么对更多数字是否成立?
  • 如果猜想不正确,至少每个猜想都是独一无二的吗?float('%.17f' % r)
Python 浮点 精度 IEEE-754 PYTHON-3.10

评论

2赞 Mark Dickinson 6/26/2022
是的,在大多数使用 IEEE 754 的系统和最近的 CPython 上,将提供任何非 NaN 浮点数(而不仅仅是范围内的浮点数)。这是 CPython 使用 David Gay 的结果,它提供了正确舍入的 str<->float 转换。但是,可能有一些系统不能使用 ,在这些系统上,使用了系统的 str<-> 浮点转换,并且无法保证您询问的相等性。float("%.17g" % x) == xTruex(0, 1)dtoa.cdtoa.c
2赞 Mark Dickinson 6/26/2022
是的,17 是用于 IEEE 754 二进制文件的正确有效位数64;在很多地方都有记录。例如,请参阅 exploringbinary.com/...
3赞 user202729 6/27/2022
@martineau 这与这个特定问题无关(它只问他们是否可以正确往返),但你的陈述实际上是错误的,每个有限的二进制值都有一个有限的十进制值。
4赞 rici 6/27/2022
@martineau:也许你打算声称不是每个十进制数都有二进制表示,但你的评论实际上说的是,不是每个二进制数都有十进制表示,这是不正确的。
3赞 chtz 6/27/2022
如果您的实际问题是精确存储二进制浮点数,为什么不将它们保存为十六进制浮点数呢?还是直接作为二进制?

答: 暂无答案