【问题标题】:What is the first value at which a IEEE 64-bit float cannot distinguish two integers?IEEE 64 位浮点数无法区分两个整数的第一个值是多少?
【发布时间】:2018-12-27 17:28:47
【问题描述】:

我指望Double(符合IEEE 的64 位浮点数)来跟踪一些非常大的数字。问题是我需要保持整数的单位分辨率(那些地方)。

问题是我知道,随着 IEEE 浮点值的增加,它们的精度会降低。我确信在某个时候,我们会得到这样的结果:

...
xxxxxxxxxxxxxxxxx04
xxxxxxxxxxxxxxxxx05
xxxxxxxxxxxxxxxxx06
xxxxxxxxxxxxxxxxx08
xxxxxxxxxxxxxxxxx10
...

其中一些整数根本无法表示。我想知道那个点在哪里,以便我能够防范它、警告用户或制定公司政策。


请注意,我使用浮点数是有充分理由的;小数部分对应用程序也很重要,但远不如整数部分重要。

【问题讨论】:

    标签: integer double precision ieee-754


    【解决方案1】:

    IEEE-754 基本 64 位二进制浮点格式使用 53 位有效位。它编码的每个有限数的形式为 sF • 2e,其中 s em>(符号)为+1或-1,F(小数)为53位二进制数b的个数。bbb em>…bbb(注意第一位后面的“.”),e 是从 -1022 到 +1023 的指数。 (通常,浮点数通过位移位以将前 1 位移动到前导 b 位置并调整指数来补偿来标准化。关于可表示值的讨论,我们可以忽略这一点;所有可以用前导 0 表示的数字也可以用前导 1 表示,只要指数在范围内,这是针对这个问题的。)

    这告诉我们回答问题所需的一切。从 0 到 253−1 的每个整数都可以用 +1 的形式表示 • b.bbbbbb • 252 表示位 b.bbbbbb 的一些值组合。并且 253 可以表示为 +1 • 1.000…000 • 253。但是 253+1 是不可表示的,因为它需要 1.000…0001 形式的 F,其中需要 54 位(第一个用于 253 和最后一个为 20)。

    之后,253+2 是可表示的,因为跨越它的最高和最低 1 位只需要 53 位(从 253 到 21)。所以,在这个量级上,偶数是可表示的,而奇数是不可表示的。

    因此,从连续可表示整数到不可表示整数的转换如下所示:

    • 9,007,199,254,740,919 = 253-3 是可表示的。
    • 9,007,199,254,740,920 = 253−2 是可表示的。
    • 9,007,199,254,740,921 = 253-1 是可表示的。
    • 9,007,199,254,740,922 = 253 是可表示的。
    • 9,007,199,254,740,923 = 253+1 不可表示。
    • 9,007,199,254,740,924 = 253+2 是可表示的。
    • 9,007,199,254,740,925 = 253+3 不可表示。
    • 9,007,199,254,740,926 = 253+4 是可表示的。

    【讨论】:

    • 感谢您的解释!
    【解决方案2】:

    根据Wikipedia

    任何绝对值小于2的整数24都可以用单精度格式精确表示,任何绝对值小于2的整数53都可以以双精度格式精确表示。 此外,可以表示这种数字的 2 倍的广泛幂。这些属性有时用于纯整数数据,以便在具有双精度浮点但只有 32 位整数的平台上获取 53 位整数。

    强调我的

    也就是说,IEEE 64 位的最高整数精度数是 9,007,199,254,740,992,其次是 9,007,199,254,740,994。以您的问题格式:

    9007199254740990
    9007199254740991
    9007199254740992
    9007199254740992
    9007199254740994
    9007199254740996
    9007199254740996
    

    请注意,一些浮点到字符串的算法会这样打印:

    9007199254740990.0
    9007199254740991.0
    9007199254740992.0
    9007199254740992.0
    9.007199254740994e+15
    9.007199254740996e+15
    9.007199254740996e+15
    

    【讨论】:

    • 我相信 OP 的示例列表是可表示值的列表,而不是连续整数转换为格式的结果列表。鉴于此,您的列表不正确;它应该是…91,…92,…94,…96,…无论如何,我不知道有任何软件可以为任何 IEEE-754 64 位二进制值打印…93 数字。
    • 我不确定你在说什么。我是 OP,这些是通过分别在 JavaScript 和 Swift 中将 06 添加到 9007199254740990 生成的。
    • 我明白你对 ...93 数字的意思。谢谢你指出;我已经更正了。
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    相关资源
    最近更新 更多