数字1,右移了任何大于0的值,应该是0,对吗?然而,我可以输入这个非常简单的程序,它打印1。
#include <stdio.h>
int main()
{
int b = 0x80000000;
int a = 1 >> b;
printf("%d\n", a);
}在linux上用gcc测试过。
发布于 2011-09-30 04:55:11
6.5.7按位移位操作符:
如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
显然,编译器可以做任何事情,但最常见的行为是完全优化表达式(以及任何依赖于它的东西),或者简单地让底层硬件为超出范围的移位做任何事情。许多硬件平台(包括x86和ARM)屏蔽了一些低阶位,以用作移位量。实际的硬件指令将给出您在这两个平台上观察到的结果,因为移位量被屏蔽为零。因此,在你的例子中,编译器可能已经优化了移位,或者它可能只是让硬件做它所做的任何事情。如果您想知道是哪一个,请检查程序集。
发布于 2011-09-30 05:00:57
根据标准,移位的位数超过实际存在的位数会导致未定义的行为。所以我们不能为此责怪编译器。
动机可能在于0x80000000的“边界意义”,它位于最大正负值的边界(也就是“负”位设置的最高位),以及应该完成的某些检查,编译后的程序不会浪费时间来验证“不可能”的事情(您真的希望处理器将位移位30亿次吗?)。
发布于 2011-09-30 05:42:24
好吧,读一读可能会对你有所帮助
expression1 >> expression2
>>操作符会屏蔽expression2,以避免过多地移动expression1。
这是因为如果移位量超过expression1数据类型中的位数,则所有原始位都将被移位,从而产生微不足道的结果。
现在,为了确保每个移位至少留下一个原始位,移位运算符使用以下公式来计算实际移位量:
使用比expression1中的位数少一的位数对expression2进行掩码(使用按位AND运算符)。
示例
var x : byte = 15;
// A byte stores 8 bits.
// The bits stored in x are 00001111
var y : byte = x >> 10;
// Actual shift is 10 & (8-1) = 2
// The bits stored in y are 00000011
// The value of y is 3
print(y); // Prints 3"8-1“是因为x是8字节,所以操作数将是7位。该空位移除了原始链位最后一位
https://stackoverflow.com/questions/7603279
复制相似问题