int z = 1;
z <<= 31;
z >>= 31;
printf ("%d\n",z);
Run Code Online (Sandbox Code Playgroud)
当我运行代码时z=-1
,为什么?
int z = 1;
z <<= 31;
Run Code Online (Sandbox Code Playgroud)
假设使用了int
32位且使用了二进制补码表示,左移位是C中未定义的行为,因为结果如果在int
类型中不可表示.从标准:
E1 << E2的结果是E1左移E2位位置
...
如果E1具有带符号类型和非负值,并且E1×2 E2可在结果类型中表示,那么这就是结果值; 否则,行为未定义.
在实践中,它很可能导致0x80000000
,被视为负数.
负整数的右移是实现定义的行为:
E1 >> E2的结果是E1右移E2位位置.
...
如果E1具有带符号类型和负值,则结果值是实现定义的.
在C++中,左移是以类似的方式定义,直到C++ 14,正如@TC所提到的(或者,有一些限制,甚至可能是直到C++ 11,如@MattMcNabb所写).
但即使定义了左移并且0x8000000
是预期值,负数的右移结果仍然是实现定义的.
是的,移位有符号整数和负数是我相信的实现定义.
当你向右移动时,你的实现可能会进行符号位扩展.
因此,不是从左侧移动零,而是在符号位中移位.z <<= 31;
可能是将符号位设置为1,然后z >>= 31;
从左侧移位,所以最终得到的位模式0xFFFFFFFF
被解释为-1
平台上的值(可能使用两个补码).
归档时间: |
|
查看次数: |
2198 次 |
最近记录: |