可以表示为浮点数的最大奇数整数

时间:2018-09-11 00:40:43

标签: c bit data-representation

我想知道什么最大的奇数整数可以精确地表示为浮点数?以及为什么在这种情况下表示为浮点数的最大偶数整数之间存在差异。

我相信它必须与2的指数2 ^ n-1有关,但是我对C语言中的数据表示不够熟悉,无法看到区别。

1 个答案:

答案 0 :(得分:1)

可表示为32位浮点数的最大奇数整数是2 ^ 24-1。

更具体地说,一个32位浮点数可以准确表示以下整数:

  • 所有不超过2 ^ 24的整数
  • 最大2 ^ 25的所有偶数整数
  • 4的所有倍数,最高2 ^ 26
  • 8的所有倍数,最高2 ^ 27

换句话说,这是可精确表示的整数:

0
1
2
...
16777215
16777216 (= 2^24)
16777218
16777220
...
33554430
33554432 (= 2^25)
33554436
33554440
...
67108860
67108864 (= 2^26)
67108872
67108880
...

请注意,这适用于正整数和负整数,例如,可以精确表示所有小于-2 ^ 24的负整数。

下面是一些C ++代码对2 ^ 24、2 ^ 25和2 ^ 26附近的整数进行整数到浮点转换,以便在实践中看到这一点。

Live on Coliru

#include <iostream>
#include <iomanip>
#include <vector>

int main()
{
    int _2pow24 = 1 << 24;
    int _2pow25 = 1 << 25;
    int _2pow26 = 1 << 26;
    std::cout << "2^24 = " << _2pow24 << std::endl;
    std::cout << "2^25 = " << _2pow25 << std::endl;
    std::cout << "2^26 = " << _2pow26 << std::endl;
    std::vector<int> v;
    for (int i = -4; i < 4; ++i) v.push_back(_2pow24 + i);
    for (int i = -8; i < 8; ++i) v.push_back(_2pow25 + i);
    for (int i = -16; i < 16; ++i) v.push_back(_2pow26 + i);
    for (int i : v) {
        std::cout << i << " -> "
                  << std::fixed << std::setprecision(1)
                  << static_cast<float>(i)
                  << std::endl;
    }
    return 0;
}

输出:

2^24 = 16777216
2^25 = 33554432
2^26 = 67108864
16777212 -> 16777212.0
16777213 -> 16777213.0
16777214 -> 16777214.0
16777215 -> 16777215.0
16777216 -> 16777216.0
16777217 -> 16777216.0
16777218 -> 16777218.0
16777219 -> 16777220.0
33554424 -> 33554424.0
33554425 -> 33554424.0
33554426 -> 33554426.0
33554427 -> 33554428.0
33554428 -> 33554428.0
33554429 -> 33554428.0
33554430 -> 33554430.0
33554431 -> 33554432.0
33554432 -> 33554432.0
33554433 -> 33554432.0
33554434 -> 33554432.0
33554435 -> 33554436.0
33554436 -> 33554436.0
33554437 -> 33554436.0
33554438 -> 33554440.0
33554439 -> 33554440.0
67108848 -> 67108848.0
67108849 -> 67108848.0
67108850 -> 67108848.0
67108851 -> 67108852.0
67108852 -> 67108852.0
67108853 -> 67108852.0
67108854 -> 67108856.0
67108855 -> 67108856.0
67108856 -> 67108856.0
67108857 -> 67108856.0
67108858 -> 67108856.0
67108859 -> 67108860.0
67108860 -> 67108860.0
67108861 -> 67108860.0
67108862 -> 67108864.0
67108863 -> 67108864.0
67108864 -> 67108864.0
67108865 -> 67108864.0
67108866 -> 67108864.0
67108867 -> 67108864.0
67108868 -> 67108864.0
67108869 -> 67108872.0
67108870 -> 67108872.0
67108871 -> 67108872.0
67108872 -> 67108872.0
67108873 -> 67108872.0
67108874 -> 67108872.0
67108875 -> 67108872.0
67108876 -> 67108880.0
67108877 -> 67108880.0
67108878 -> 67108880.0
67108879 -> 67108880.0