当前位置: 首页 > 知识库问答 >
问题:

浮动到字符串往返测试

钱承允
2023-03-14

我认为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.')

如果将 IEEE 754 双精度转换为至少包含 17 位有效数字的十进制字符串,然后转换回双精度,则最终数字必须与原始数字匹配。

共有1个答案

巴宏恺
2023-03-14

在我最初的测试中,我是对小数字进行操作的,所以有很多前导零,它们不是有效数字。浮点数需要17个有效数字才能正确表示。通过像这样更改一行,我使数字变大,并且能够在小数点后仅16位数字的情况下成功。

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

最好的方法似乎是根本不使用格式(),而是使用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)):
 类似资料:
  • 问题内容: 我一点都不熟悉PHP,并且有一个简短的问题。 我有2个变量和。这是将这些设置为值的代码: 如果输出,则得到正确的值。可以说发票单位和价格。 现在,我需要显示花费的总额。当我将这两者相乘时,它不起作用(正如预期的那样,它们是字符串)。 但是我不知道如何在PHP中解析/广播/转换变量。 我该怎么办? 问题答案: 应该为你做。查看Type-Juggling。您还应该阅读将String转换为N

  • 正如在许多地方所解释的那样(例如,为什么十进制数不能用二进制精确表示?),并非所有小数部分都可以表示为浮点值(例如存储在Java中的中)。 给出的典型例子是“0.2”。根据这个漂亮的IEEE 754转换器,最接近0.2的大约是0.20000000298023224,所以将“0.2”解析为应该会产生这个结果。 然而,我注意到Java似乎能够做到不可能的事情: 印刷品: 往返字符串的结果- 在IDeo

  • 输入变量是一个字符串,例如我想将其格式化为浮动,这样我的输出将是 我检查了NumberFormat类以完成任务,但无法在最后将变量格式化为浮动 就目前而言,我使用以下方法正确获得字符串结果: 如何返回而不是?

  • 问题内容: 有没有一种简单的方法来测试Python字符串“ xxxxABCDyyyy”,以查看其中是否包含“ ABCD”? 问题答案: if “ABCD” in “xxxxABCDyyyy”: # whatever

  • GETRANGE key start end 返回key 中字符串值的子字符串,字符串的截取范围由start 和end 两个偏移量决定(包括start 和end 在内)。可以使用负值,字符串右面下标是从-1开始的。 注意返回值处理: 1: start>=length, 则返回空字符串 2: stop>=length,则截取至字符结尾 3: 如果start 所处位置在stop右边, 返回空字符串

  • 我有以下JSON字符串: 我只想要和。我试过这样的方法: 但我得到了以下错误: 我只使用过几次JSON。有人能帮我吗? 对我来说最好的例子是这样的,我在另一个例子中做过: 可能吗? 现在我已经做到了: 我试着这样做: 然后: 但现在当我做一个Prtinout时,我会得到和以前一样的错误: