多大范围内的整数可以用浮点数精确表示

本文探讨了IEEE754浮点数表示的局限性,通过实验发现从±16777217开始,浮点数无法确保精确转换回整数。这是因为浮点数在224的位置精度最密集,能精确表示的整数范围为±224。文章解释了这一现象背后的二进制表示原理,并通过浮点数的规格化形式进行了解释。
摘要由CSDN通过智能技术生成

转载自https://airguanz.github.io/2019/11/20/float-to-int-exact-range.html

  

我们知道,IEEE 754中的浮点数是对实数的近似表示,其取值密度在越远离0的地方越稀疏。那么,究竟在多远处浮点数会无法精确地cast到整数呢?本文对此进行了实验和分析。

实验代码很简单:

int main()
{
    for(int i = 0; i < std::numeric_limits<int>::max(); ++i)
    {
        float f = static_cast<float>(i);
        if(i != static_cast<int>(f))
        {
            cout << i << endl;
            break;
        }
    }

    for(int i = 0; i > std::numeric_limits<int>::min(); --i)
    {
        float f = static_cast<float>(i);
        if(i != static_cast<int>(f))
        {
            cout << i << endl;
            break;
        }
    }
}

这段代码在VS2019中的输出如下:

16777217
-16777217

也就是说,从+-16777217开始,我们就无法保证一个int被转为float后,还能完好无损地转回来了。对二进制数比较敏感的人可以注意到:

16777217=224+116777217=224+1

即浮点数能精确表示整数的范围为±224±224。这数字实在太“整”了,让我们试着从IEEE 754的浮点数格式中一探究竟。

注意到我们讨论的数值落在float的规格化表示范围内。float包含1个符号位,8个指数位,以及23位的尾数。设符号位为ss,阶码的无符号整数解释为ee,尾数的位表示为

f1f2…f23f1f2…f23

则规格化的浮点数取值为:

(−1)s×(1+2−1f1+2−2f2+⋯+2−23f23)×2e−127(−1)s×(1+2−1f1+2−2f2+⋯+2−23f23)×2e−127

当e−127=23e−127=23时,上式变为:

(−1)s×(223+222f1+221f2+⋯+2f22+f23)(−1)s×(223+222f1+221f2+⋯+2f22+f23)

此时根据ff每一位的值,该式可以取遍[−224+1,224−1][−224+1,224−1]中的每一个整数。而当e−127=24e−127=24且ff的所有位均为0时,±224±224也可以被精确地表示。一旦超过了这个范围,就出现了相邻的两个浮点值间的距离超过1的情况,也就无法再精确表示剩余的整数了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值