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

问题

#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值