看看下面的运算结果各是多少呢?
#define MYUINT_MAX 4294967295 //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
同样的表达式,不同的左值,结果也会是不同!基础很重要,随时温习!