前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >float类型加法精度损失问题(C++)

float类型加法精度损失问题(C++)

原创
作者头像
老狼码农
发布2018-07-19 15:15:51
2.1K0
发布2018-07-19 15:15:51
举报
文章被收录于专栏:网络和编程网络和编程

问题

代码语言:txt
复制
unsigned int a = 406682816;
a = a+1.0f;

奇怪的就是:a依然是406682816,并没有加一。网上查了一些资料,这里分享一下原因。

分析与验证

测试代码
代码语言:txt
复制
    int a=406682816;
    int c=a+1.0f;

    int mask = 1;
    // 浮点类型的a
    float fa = a; 
    // 浮点类型的a+1.0f
    float fc = a+1.0f;

    cout << a << endl;
    cout << c << endl;

    cout << endl << "a bits" << endl;
    for ( int i=31;i>=0;i-- )
    {
        cout << ((*((int*)&a))>>i & mask );
    }

    cout << endl << "fa bits" << endl;
    for ( int i=31;i>=0;i-- )
    {
        cout << ((*((int*)&fa))>>i & mask );
    }

    cout << endl << "fc bits" << endl;
    for ( int i=31;i>=0;i-- )
    {
        cout << ((*((int*)&fc))>>i & mask );
    }
    cout << endl;
输出
代码语言:txt
复制
406682816
406682816

a bits
00011000001111010111110011000000
fa bits
01001101110000011110101111100110
fc bits
01001101110000011110101111100110
// fa和fc的内存值完全一致

原因结论

float类型的内存分布在IEEE 754标准里有规定:对于大小为32-bit的浮点数(32-bit为单精度,64-bit浮点数为双精度,80-bit为扩展精度浮点数)

  1. 其第31 bit为符号位,为0则表示正数,反之为复数,其读数值用s表示;
  2. 第30~23 bit为幂数,其读数值用e表示;
  3. 第22~0 bit共23 bit作为系数,视为二进制纯小数,假定该小数的十进制值为x;

float类型的数值得出的公式计算示例如下(截自网络):

20170215225457756.png
20170215225457756.png

也即,float类型可以用于数值计算的位数少于int(只有23位),通过符号位,幂数以及系数位来做计算,示例中做了1.0f的加法后,并没有改变内存的布局,所以值并未变化。

这里也从侧面提醒我们,在做要求精度的计算时,避免使用float类型是上佳之策,否则,即是我们明白float类型的计算原理依然会踩坑..

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 分析与验证
    • 测试代码
      • 输出
      • 原因结论
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档