python - 浮点到字符串往返测试

标签 python floating-point rounding precision ieee-754

我相信 17 位小数应该足以正确表示 8 字节浮点,这样它是往返安全的(转换为字符串并返回而没有任何损失)。

但在此测试中,该数字可能高达 23,如果增加迭代次数,可能会更高。

这是一个有缺陷的测试吗?为什么?
如何确保 Python 中 float 的往返完整性?

def TestLoop():
    sFormat = ''
    success = True
    ff = [1.0/i for i in range(1,10000000)]
    for n in range(17, 31):
        sFormat = '{{:.{:d}f}}'.format(n)
        success = True
        for f in ff:
            if f != float(sFormat.format(f)):
                success = False
                break
        if success:
            return(n)
    return(-1)

n = TestLoop()   
print('Lossless with ', n, ' decimal places.')

If an IEEE 754 double precision is converted to a decimal string with at least 17 significant digits and then converted back to double, then the final number must match the original.

最佳答案

在我最初的测试中,我对小数字进行操作,因此有很多前导零,它们不是有效数字。 float 需要 17 位有效数字才能正确表示。通过像这样更改一行,我将数字变大,并且成功地只保留了小数点后 16 位。

ff = [10000000.0/i for i in range(1,10000000)]

最好的方法似乎是根本不使用 format(),而是使用 repr()str() .
此代码此处成功:

def TestLoop():
    for i in range(1, 10000000):
        f = 1.0 / i
        if f != float(repr(f)):
            print('Failed.')
            return
    print('Succeeded.')
    return

TestLoop()

另一种有效的方法是使用小数点后 17 位数字,但使用 g 格式化程序而不是 f。这使用指数,因此消除了前导零。

if f != float('{:.17g}'.format(f)):

关于python - 浮点到字符串往返测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32685380/

相关文章:

python - 是否有可能像在 Matlab 中一样快地在 Python 中计算稀疏矩阵的逆矩阵?

python - 在 wxpython 中使用 cairo 绘图

python - 从 for 循环返回 false,否则在 F# 中继续

c++ - 浮点加法向上舍入

c# - Excel RoundUp 与 .NET Math.Round

python - PyPy/RPython 可以用来生成一个小的独立可执行文件吗?

c - Double 不在 C 中存储数字(数字太小)

python - 在 Python 中,小 float 趋于零

floating-point - 尾数有效位

MYSQL 舍入问题