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