关闭

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

标签: 字段类型转化
271人阅读 评论(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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:64888次
    • 积分:1591
    • 等级:
    • 排名:千里之外
    • 原创:79篇
    • 转载:13篇
    • 译文:3篇
    • 评论:13条
    最新评论