为什么在C中右移负数会使最左边的位数为1?

Nik*_*nka 6 c bit-manipulation bit-shift

赫伯特·希尔特(Herbert Schildt)的书"C完整参考文献"中说"(在有符号的负整数的情况下,右移将导致1被引入,以便保留符号位.)"

保留标志位有什么意义?

此外,我认为这本书是指使用符号位表示负数而不使用二进制补码的情况.但即使在这种情况下,推理似乎也没有任何意义.

caf*_*caf 15

Schildt书被广泛认为特别差.

实际上,当你右移一个带负号的数字时,C 不能保证1会被移入; 右移右值的结果是实现定义的.

然而,如果负数的右移位定义在1s至移位到最高位的位置,然后在一个2的补码表示将表现为一个算术移位 -用N向右移位的结果将是相同的分频2 N,向负无穷大四舍五入.

  • @JagsVG:例如,如果你有8位2s补码二进制数11111101表示-3的十进制数,你执行算术右移给11111110表示-2的十进制数,这与-3除以2相同^ 1,给-1.5向负无穷大舍入,得到-2. (4认同)
  • 你可以解释一下这句话"N向右移的结果与除以2 ^ N的结果相同,向负无穷大四舍五入."? (2认同)

Jon*_*ler 7

这个声明是彻底和不准确的,就像席尔特先生的许多声明一样.很多人建议扔掉他的书.(在其他地方,请参阅Annotated Annotated C标准ACCU评论 - 在Schildt上进行作者搜索;另请参阅Stack Overflow上的C书最终列表).

实现定义是否正向移位负(必须符号)整数将零或1移位到高位.底层的CPU(例如,ARM ;还参见此)通常具有两种不同的底层指令- ASR或算术右移和LSR或逻辑右移,其中ASR保留符号位和LSR没有.允许编译器编写者选择其中之一,并且可能出于兼容性,速度或奇思妙想的原因这样做.

ISO/IEC 9899:2011§6.5.7按位移位算子

5结果E1 >> E2E1右移位E2位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/2 E2的商的整数部分.如果E1具有有符号类型和负值,则结果值是实现定义的.