Python 浮子串往返试验

Python 浮子串往返试验,python,floating-point,rounding,precision,ieee-754,Python,Floating Point,Rounding,Precision,Ieee 754,我认为,17位小数应该足以正确表示8字节浮点,这样它就可以安全地往返(转换为字符串并返回而不丢失) 但是在这个测试中,这个数字可能会高达23,如果增加迭代次数,这个数字可能会更高 这是一个有缺陷的测试吗?为什么? 在Python中如何确保浮点的往返完整性 def TestLoop(): sFormat = '' success = True ff = [1.0/i for i in range(1,10000000)] for n in range(17, 31)

我认为,17位小数应该足以正确表示8字节浮点,这样它就可以安全地往返(转换为字符串并返回而不丢失)

但是在这个测试中,这个数字可能会高达23,如果增加迭代次数,这个数字可能会更高

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

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.')

在我最初的测试中,我对小数字进行运算,因此有很多前导零,它们不是有效数字。浮点数要求正确表示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)):

在我最初的测试中,我对小数字进行运算,所以有很多前导零,它们不是有效数字。浮点数要求正确表示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)):

是的,在这里使用
.17g
进行格式化是正确的方法
.16e
也可以工作。不要在Python2上使用
str
:它没有给出足够的数字。但是,
repr
可以。(在Python3的最新版本中,
str
repr
对于浮点数是相同的。)是的,使用
.17g
进行格式化是正确的方法
.16e
也可以工作。不要在Python2上使用
str
:它没有给出足够的数字。但是,
repr
可以。(在Python3的最新版本中,
str
repr
对于浮点是相同的。)