我有一个这样的测试程序:
int main()
{
unsigned n = 32;
printf("ans << 32 = 0x%X\n", (~0x0U) << 32);
printf("ans >> 32 = 0x%X\n", (~0x0U) >> 32);
printf("ans << n(32) = 0x%X\n", (~0x0U) << n);
printf("ans >> n(32) = 0x%X\n", (~0x0U) >> n);
return 0;
}
它产生以下输出:
ans << 32 = 0x0 ... (1)
ans >> 32 = 0x0 ... (2)
ans << n(32) = 0xFFFFFFFF ... (3)
ans >> n(32) = 0xFFFFFFFF ... (4)
我期望(1)和(3)相同,以及(2)和(4)相同。
使用gcc版本:gcc.real(Ubuntu 4.4.1-4ubuntu9)4.4.1
怎么了?
根据C标准 §6.5.7.3
,按类型大小移动是未定义的行为:
6.5.7按位移位运算符
(…)如果右操作数的值为负或大于 或等于 提升后的左操作数的宽度,则行为未定义。
您的编译器应就此警告您:
$ gcc shift.c -o shift -Wall
shift.c: In function ‘main’:
shift.c:5:5: warning: left shift count >= width of type [enabled by default]
shift.c:6:5: warning: right shift count >= width of type [enabled by default]
如果看一下gcc生成的汇编代码,您会发现它实际上是在编译时计算前两个结果。简化:
main:
movl $0, %esi
call printf
movl $0, %esi
call printf
movl -4(%rbp), %ecx ; -4(%rbp) is n
movl $-1, %esi
sall %cl, %esi ; This ignores all but the 5 lowest bits of %cl/%ecx
call printf
movl -4(%rbp), %ecx
movl $-1, %esi
shrl %cl, %esi
call printf
问题内容: 我想知道如何实现由位表示的位串的k 循环 右移。 这些代码所做的全部是 返回0 ,如何使其循环移位? 问题答案: 这应该工作: 另请参阅Wikipedia上有关循环移位的文章。
今天我学习了左移位运算符()。正如我所理解的,左移位运算符将位移动到指定的左边。我也知道乘以2表示移位。但是我很困惑,比如“移位”到底是什么意思,为什么当赋值的类型不同时,输出会有所不同? 当我调用下面的函数时,它给出的输出为
问题内容: 当遇到按位移位运算符时,我遇到了一个有趣的场景。如果第二个操作数为负,按位移位运算如何工作?。 即,<< << b,“ <<”将a中的位模式向左移动b位。但是,如果b为负数,在运行时是否应该出错? 我能够成功运行以下代码,但我不知道它是如何工作的? 输入项 结果 “ a”的ASCII码为97。有人可以帮助我了解其工作原理吗? 问题答案: 但是,如果b为负数,在运行时是否应该出错? 不符
static->http://localhost:8080 dev webserver->http://localhost:8080/dev 我将其他几个服务绑定到不同的位置指令。 null null 所以现在我有点不知道如何解决这个问题。
问题内容: 考虑以下代码(其中byteIndex是一个int): 这会产生错误 编译时(必需字节,位于int)。 代码 编译良好。 这是什么问题,我该如何解决第一个示例以允许将整数值按int值进行移位? 编辑:根据评论,这是一个更完整的示例: 和给出的错误是: 问题答案: 将您的行转换为此:- 您的RHS是一个整数,您需要将其转换为字节。 上面的代码将正常工作..不管有没有的到 因此,您也可以:-
问题内容: 在使用on进行位移时,我注意到使用无符号右移()时会得到奇怪的结果。使用,右移(有符号:和无符号:)的行为均符合预期: 但是当我对进行相同操作时,无符号右移会发生奇怪的事情: 我认为可能是编译器正在内部将转换为,但似乎不足以解释这种行为。 为什么在Java中以字节的方式进行位移位? 问题答案: 这种情况正是因为被晋升到前执行按位运算。表示为: 因此,向右移至7或8位仍保留第7位1,因此