可以精确表示为浮点数/双精度浮点数的整数范围

8
什么是可以表示为double(或float)的(连续)整数的确切范围?我问这个问题是因为我对类似于此类问题的精度损失感到好奇。
也就是说,
  1. 最小的正整数m是多少,以至于m + 1无法准确表示为double(或float)?
  2. 最大的负整数-n是多少,以至于-n-1不能准确表示为double(或float)?(可能与上述相同)。
这意味着介于-n和m之间的每个整数都具有精确的浮点表示。 我基本上正在寻找浮点数和双倍数的范围[-n,m]。

让我们将范围限制在标准IEEE 754的32位和64位浮点表示上。 我知道float具有24位精度,double具有53位精度(两者都带有隐藏的前导位),但由于浮点表示的复杂性,我正在寻找权威答案。请不要含糊其辞!

(理想答案将证明从0m的所有整数都是可表达的,而m+1则不是。)

1个回答

8

既然您在问IEEE浮点类型,那么编程语言并不重要。

#include <iostream>
using namespace std;

int main(){

    float f0 = 16777215.; // 2^24 - 1
    float f1 = 16777216.; // 2^24
    float f2 = 16777217.; // 2^24 + 1

    cout << (f0 == f1) << endl;
    cout << (f1 == f2) << endl;

    double d0 = 9007199254740991.; // 2^53 - 1
    double d1 = 9007199254740992.; // 2^53
    double d2 = 9007199254740993.; // 2^53 + 1

    cout << (d0 == d1) << endl;
    cout << (d1 == d2) << endl;
}

输出:

0
1
0
1

浮点数的限制是2^24,双精度浮点数的限制是2^53。负数同样适用,因为唯一的区别是符号位。


我添加了语言标签,因为其他标签没有流量。不过还是谢谢你的回答! - Andrew Mao
Kyurem在他的分析中非常准确。但是,如果你想要一个经验性的解决方案,只需使用for循环进行测试:float f = 0; for (;;++f) { if (f == (f+1)) { cout << f; break; } }。双精度和负数同理。 - Scott Mermelstein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接