0

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

1111 1111 1111 1111 1111 1111 1111 1111

4

4 回答 4

2

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

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

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

由于是非负的,因此结果是其明显为零1的积分商。1 / (2^31)

于 2012-10-04T22:04:02.727 回答
2

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

0000 0000 0000 0000 0000 0000 0000 0001
^
于 2012-10-04T22:05:06.793 回答
0

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

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

于 2012-10-04T22:07:35.667 回答
0

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

#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;
}
于 2021-01-28T05:01:28.080 回答