关闭

一个自动类型转化导致的bug

标签: 字段类型转化
377人阅读 评论(0) 收藏 举报
分类:

问题

#include <iostream>
#include <stdint.h>
#include <cassert>

int main()
{
    uint32_t now = time(0) ;
    float gap = 104 ;
    uint32_t should = now + 104 ;
    uint32_t but = now + gap ;
    assert(but == should);
    return 0 ;
}

好 , 编译执行~

a.out: test.cpp:11: int main(): Assertion `but == should’ failed.
Aborted

这个。。。 如果我们打印出but 变量的值, 会发现误差在两位数!

原因其实也很简单 :

#include <iostream>
#include <stdint.h>
#include <cassert>
#include <typeinfo>

int main()
{
    uint32_t now = time(0) ;
    float gap = 104 ;
    uint32_t should = now + 104 ;
    uint32_t but = now + gap ;
    assert ( typeid(now+gap) == typeid(float) );
    assert (typeid(now +104) == typeid(uint32_t) ) ;
    //assert(but == should);
    return 0 ;
}

Woo , 通过~
显然这里是 now+gap 的结果被首先存储在float中, 然后转化为uint32_t , 转化的过程中丢失了精度!


自动类型提升

是的 , 上面的问题就是c/c++ 的一个基本的概念 : 自动类型提升。

规则是这样的 :

First, in most circumstances, values of type char and short int are converted to int right off the bat.
[简译: char 和 short –> int ]
2.If an operation involves two operands, and one of them is of type long double, the other one is converted to long double.
[简译:有long double 就都是long double ]
3.If an operation involves two operands, and one of them is of type double, the other one is converted to double.
[简译:有 double 就都是 double ]
4.If an operation involves two operands, and one of them is of type float, the other one is converted to float.
[简译:有 float 就都是 float ]
5.If an operation involves two operands, and one of them is of type long int, the other one is converted to long int.
[简译:有 long int 就都是 long int ]
6.If an operation involves both signed and unsigned integers, the situation is a bit more complicated. If the unsigned operand is smaller (perhaps we’re operating on unsigned int and long int), such that the larger, signed type could represent all values of the smaller, unsigned type, then the unsigned value is converted to the larger, signed type, and the result has the larger, signed type. Otherwise (that is, if the signed type can not represent all values of the unsigned type), both values are converted to a common unsigned type, and the result has that unsigned type.
[简译:同宽度的有/无符号 就都是无符号 ]
7.Finally, when a value is assigned to a variable using the assignment operator, it is automatically converted to the type of the variable if (a) both the value and the variable have arithmetic type (that is, integer or floating point), or (b) both the value and the variable are pointers, and one or the other of them is of type void *.
[简译:对于数字和指针的赋值运算自动转化 ]

前面的规则的优先级比后面高。

0
0
查看评论

程序bug致损失400亿,判程序员坐牢? 搞笑我们是认真的

号外!号外!走过,路过,不要错过!日本 IT 业的狗血八卦继续独家放送啦!!2015 年 9 月 3 日,随着东京最高法院驳回瑞穗证券的上诉,维持二审的原判结果,一个长达 10 年的诉讼终于画下了句号。这个判例将对 IT 行业产生深远的影响:如果程序的 bug 导致了巨大的经济损失,应该由谁来承担?...
  • mao0514
  • mao0514
  • 2016-03-30 15:13
  • 2222

(转)惨烈:1个Bug,45分钟损失4亿多美元

惨烈:1个Bug,45分钟损失4亿多美元2016-09-29 程序员的那些事 http://mp.weixin.qq.com/s?__biz=MjM5OTA1MDUyMA==&mid=2655436975&idx=1&sn=c42751b73b287ca907b897702...
  • wowotuo
  • wowotuo
  • 2016-09-30 08:55
  • 1519

关于zeromemory函数 与ascii unicode的bug与困惑

//程序选择的编码方式unicode 但是由于程序的一些函数需要调用ascii函数 只能共同调用 #include #include using namespace std; //查找文件辅助结构 struct fileName   {  ...
  • ljq550000
  • ljq550000
  • 2012-03-25 11:35
  • 423

一个奇葩bug的解决

关于这个bug发现4种现象: (1)PC端接收不到设备端应用程序采集通过网络发送的图像 (2)PC端可以ping通设备端,telnet可以登录设备,设备ping PC端只能通一个数据包 (3)设备端sleep会阻塞 (4)设备端date系统时间走180s回跳
  • skyflying2012
  • skyflying2012
  • 2015-03-25 16:49
  • 3764

整形溢出导致的bug, 前后耗费至少10分钟

unsigned long long是64位无符号整形,最近随手写了如下这行代码, 导致结果超出预期, 一起来看看: unsigned long long tmpTime = time(NULL) * 1000; // 计算毫秒         知道...
  • stpeace
  • stpeace
  • 2017-01-22 23:39
  • 2410

最近回味SSH框架,发现同事的小bug NoSuchMethod $Proxy.add(), 解决办法和根本原因

选用框架 Spring4+hibernate5+struts2 .   原因 : 在配置Aop切点的时候把Action类也拦截了 , 自定义的action是继承自actionSupport的 最后发现报了这样一个异常:  java....
  • bacchusgift
  • bacchusgift
  • 2017-08-17 13:17
  • 196

定时器实现过程的bug总结

定时器是参考linux内核定时器设计实现的. 遇到了两个比较致命而且比较隐蔽的bug. 用了各种方法debug才好不容易找到bug, 看来是确实是代码写挫了. bug1:          在后一个时...
  • akheyun
  • akheyun
  • 2011-05-02 06:48
  • 432

一个诡异BUG引发的血案(线程死锁造成的CPU利用率逐渐增高)

我首先声明,我有一些标题党的嫌疑,确实没有什么血案发生,顶多是我找BUG 时由于太用力把嘴唇给咬破了。
  • x32sky
  • x32sky
  • 2016-02-27 16:29
  • 2928

数据类型转化Bug

以下Bug是在做APP时数据封装时类型转换遇到的问题以及原因。
  • Joker_Fei
  • Joker_Fei
  • 2017-03-15 20:35
  • 108

unserialize的整型溢出错误

同事使用wnmp环境做本地开发,但是当从linux测试服务器中导出数据在本地调试的时候,发现使用unserialize函数解析序列化数据时报错: Notice: unserialize() [function.unserialize]: Error at offset 741 of 1242 by...
  • rainyse
  • rainyse
  • 2015-10-30 14:24
  • 310
    个人资料
    • 访问:86250次
    • 积分:1811
    • 等级:
    • 排名:千里之外
    • 原创:80篇
    • 转载:13篇
    • 译文:3篇
    • 评论:14条
    最新评论