C中的算术右移

时间:2012-10-04 22:00:42

标签: c bit-manipulation bit-shift

在C中,在32位机器上,我只是想知道1>>31返回-1给定1是一个有符号整数,因为对于2的补码,同时做右移(算术),复制符号位给出结果

1111 1111 1111 1111 1111 1111 1111 1111

4 个答案:

答案 0 :(得分:2)

不,在任何符合要求的实施中,结果都为零。

C99,6.5.7 / 5(“按位移位运算符”)声明:

  

E1>的结果> E2是E1右移E2位位置。如果E1有   无符号类型或E1具有带符号类型和非负值,   结果的值是E1 /的商的不可分割的一部分   2 ^ E2。如果E1具有带符号类型和负值,则为结果值   是实现定义的。

由于1是非负的,因此结果是1 / (2^31)的整数商,显然为零。

答案 1 :(得分:2)

结果将为零,因为整数1的符号位(最高有效位)为0:

0000 0000 0000 0000 0000 0000 0000 0001
^

答案 2 :(得分:0)

1>>31的结果为零,因为符号位为1。

但是,你不能指望被复制的符号位,因为根据K& R第二版,结果是为签名值的右移定义的实现。

答案 3 :(得分:0)

对于使用 int 的二进制补码表示的实现,以下代码有助于确定右移是否是有符号整数的算术运算。

#include <stdio.h>

//below function returns 1 if system is little endian, 0 otherwise
int is_little_endian() { //checks endianness
  short x = 0x0100; //256
  char *p = (char*) &x;
  if (p[0] == 0) {
    return 1; 
  }
  return 0;
}

/* Below function returns 1 if shifts are arithmetic, 0 otherwise.
   It checks whether the most significant bit is 1 or 0, for an int which
   had most the significant bit as 1 prior to the right shift. If the MSB
   is 1 after the bit shift, then the (unsigned) value of the most
   significant Byte would be 255.
*/

int int_shifts_are_arithmetic() {
  int x = -2;
  x = x >> 1 ;
  char *px = (char*)&x;
  if (is_little_endian()) {
    unsigned char *upx = (unsigned char*)&px[(int)sizeof(int) - 1];
    if (upx[0] == 255) return 1; 
    return 0;
  } else { //big endian
    unsigned char* upx = (unsigned char*)px;
    if (upx[0] == 255) return 1;
    return 0;
  }
}

int main() {
  if (int_shifts_are_arithmetic()) {
    printf("Shifts are arithmetic\n");
  }
  else {
    printf("Shifts are not arithmetic\n");
  }
  return 0;
}