通过左移,可以将1设置为零

问题描述

我对Left Shift运算符有一个困惑

int a =1;
cout<<"size of int: "<<sizeof(int)<<endl;
cout <<(a<<31)<<endl;
cout <<(a<<32)<<endl;

结果:

size of int: 4 -2147483648 1

如果我向左移动32或33,它将打印1。 如何以及为什么为1,如果我想将1左移为零,该怎么做? 谢谢。

解决方法

不允许将1的值转换为有符号整数的符号位。这样做是undefined behavior。如果这样做,则不能保证编译器会产生任何特定的结果。

类似地,移位大于或等于所讨论整数的位宽(无论是带符号的还是无符号的),也会引起未定义的行为。

C standard的第6.5.7节第2和第3段中有关按位移位运算符的规定:

3 对每个操作数执行整数提升。结果的类型是提升后的左操作数的类型。 如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为是不确定的。

4 E1 << E2的结果是E1左移E2位的位置;空位用零填充。如果E1具有无符号类型,则结果的值为 E1×2 E2 ,与结果类型中可表示的最大值相比,模减少了1。 如果E1具有带符号的类型且非负值,并且 E1×2 E2 可表示为结果类型,则为结果值;否则,行为是不确定的。