看起来你的实现可能正在用两个补码数进行算术位移。在这个系统中,它将所有位向右移动,然后用最后一位的副本填充高位。所以对于你的例子,在这里将int视为32位:nPosVal = 00000000000000001111111111111111nNegVal = 11111111111111110000000000000001
转变后,你有:nPosVal = 00000000000000000111111111111111nNegVal = 11111111111111111000000000000000
如果将其转换回十进制,则分别得到32767和-32768。
实际上,右移向负无穷大转向。
编辑: 根据最新标准草案的 6.5.7节,负数的这种行为取决于实现:E1 >> E2的结果是E1右移E2位的位置。如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2 E2的商的整数部分。如果E1具有带符号类型和负值,则结果值是实现定义的。
他们声明的理由:C89委员会肯定了K&R授予的实施自由,不要求签署权利转移操作签署延期,因为这样的要求可能会减慢快速代码的速度,并且因为符号扩展班次的有用性是微不足道的。(在一个地方算术右移一个负2的补数整数与除以2的不一样!)
所以它的实现依赖于理论。在实践中,我从未见过一个实现在左操作数被签名时没有进行算术移位。