关于int类型和float类型的坑

近期调试时发现的坑,其实是老坑,但是隐藏的比较深。

背景是这样的,项目需要用到modbus通讯,大体的意思是想测试通讯时间,于是在两台电脑之间操作,当从站接到主站的请求时把时间放到一个地址上,这样主站读到这个地址的值与本机时间比较就得到了通讯时间(两台电脑已经通过ntp进行了时间同步)。表示时间时共用了四个寄存器地址,其中两个用来存放秒值,两个存放毫秒值。

可是在实际过程中却发现,毫秒值时时刻变化的,而秒值要每隔128秒才会变一次。非常有规律的变化。正常应该每秒都在变的啊。

先放下现象,看下面一段代码

    int a=16777217;
    int e;
    float b=1.0;
     e=b*a;
     printf("a=%d,e=%d\n",a,e);

这段代码貌似没有问题,在windows下用vs2010运行,在x86的linux下编译运行都没有问题。可是在arm-linux下运行却得到了这样的结果

a=16777217,e=16777216.

其中arm-linux编译器的版本为

arm-linux-gnueabihf-g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

而x86-linux的编译器版本为

g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)

再回头看这段代码中的这一句e=b*a.

很显然,错误出现在这里,arm-linux 编译器在此处并没有正确的处理,而是按照正常的规则:b*a,为float型和int型的相乘,将int型转为float型,计算结果是float型,再将float型转为int型,由于float型无法表示16777217这个数,就造成了精度丢失。

显然,vs2010和gcc4.4.7编译器都考虑了这种情况,能够正确的处理,而arm-linux下却没有考虑,出现了错误。


  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值