C++混合运算的类型提升和溢出

来源:互联网 发布:戴笠 毛人凤 知乎 编辑:程序博客网 时间:2024/04/23 15:49
 
 看看下面的运算结果各是多少呢?
 
 #define MYUINT_MAX4294967295//0xffffffff #define MY_MAX      4294967296//0x100000000    unsigned __int64 sz1=0, sz2=0;  sz1 = MYUINT_MAX + 1;  sz2 = MY_MAX + 1;
 
 答案是【sz1=0,sz2=4294967297】(拖选看答案)
 如果你都答对了,那么恭喜你,你的C++基础不错啊;
 如果你有答错的,那就该再静下心来温习下C++基础!
 
 类型提升
 1 为防止精度损失如果必要的话类型总是被提升为较宽的类型 
 2 所有小于整型的类型在计算之前都会被转换成整型
 3 计算出结果后再转为左值类型并赋给左值
 
 就上面的表达式来说,计算过程大致是:
 1、确定MYUINT_MAX 的类型为unsigned int,1的类型为int
 2、提升1的类型为unsigned int;
 3、计算unsigned int(MYUINT_MAX) + unsigned int(1), 结果仍为unsigned int类型,溢出得0
    11111111 11111111 11111111 11111111
 +                                                                  1
 -----------------------------------------------------------------
   100000000 00000000 00000000 00000000
 4、将溢出值0转为unsigned __int64类型,赋予sz
 
 避免赋值前溢出,要注意:
 混合运算表达式不仅要保证左值足够大,还要保证表达式计算过程中的值不超出表达式最大类型的最大值
 对于表达式中的常数,小于int类型的常数匹配为int类型,大于int类型的常数编译器会自动匹配能容纳
 该值的最小类型,如:MYUINT_MAX 匹配为unsigned int类型,而MY_MAX则应该是匹配为__int64类型。
 
 
 上述表达式改为下面的形式后正确:
 
 1、分行拆写
 unsigned __int64 sz = MYUINT_MAX;
 sz += 1;
 
 2、显式转换
 unsigned __int64 sz = (unsigned __int64)UINT_MAX + 1;
 
 有符号整数,在发生数位扩展时注意:负数是在新扩展位上补1,如:
 #define INT_MAX       2147483647 
 int nn = INT_MAX;
 unsigned int sz1 = nn + 1; //=2147483648
 //10000000 00000000 00000000 00000000
 
 __int64 sz2 = nn + 1; //=-2147483648
 //11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
 同样的表达式,不同的左值,结果也会是不同!基础很重要,随时温习!