gpt4 book ai didi

c - 为什么将变量移位超过其位宽度会清零?

转载 作者:太空宇宙 更新时间:2023-11-04 01:47:22 25 4
gpt4 key购买 nike

这个问题的灵感来自 StackOverflow 的其他问题。今天,在浏览 StackOverflow 时,我遇到了一个问题,即通过值 k 对变量进行位移,该值 >= 该变量的宽度(以位为单位)。这意味着将 32 位 int 移动 32 位或更多位。

Left shift an integer by 32 bits

Unexpected C/C++ bitwise shift operators outcome

从这些问题中可以明显看出,如果我们尝试将一个数字移位 >= 变量位宽的 k 位,则只会采用最低有效的 log2k 位。对于 32 位的 int,最低有效 5 位被屏蔽并作为移位量。

所以一般来说,如果 w = 变量的宽度(以位为单位),x >> k 变成 x >> (k % w)对于 int,这是 x >> (k % 32)

The count is masked to five bits, which limits the count range to 0 to 31.

所以我编写了一个小程序来观察理论上应该产生的行为。我在评论中写下了结果转移量 % 32。

#include <stdio.h>
#include <stdlib.h>

#define PRINT_INT_HEX(x) printf("%s\t%#.8x\n", #x, x);

int main(void)
{
printf("==============================\n");
printf("Testing x << k, x >> k, where k >= w\n");

int lval = 0xFEDCBA98 << 32;
//int lval = 0xFEDCBA98 << 0;

int aval = 0xFEDCBA89 >> 36;
//int aval = 0xFEDCBA89 >> 4;

unsigned uval = 0xFEDCBA89 >> 40;
//unsigned uval = 0xFEDCBA89 >> 8;

PRINT_INT_HEX(lval)
PRINT_INT_HEX(aval)
PRINT_INT_HEX(uval)

putchar('\n');

return EXIT_SUCCESS;
}

并且输出与移位指令的预期行为不匹配!

==============================
Testing x << k, x >> k, where k >= w
lval 00000000
aval 00000000
uval 00000000

============================================= ======================

其实我对 Java 有点困惑。在 C/C++ 中,将 int 移动大于位宽的位数可能会减少 k % w,但这不是 C 标准所保证的。没有规定说这种行为应该一直发生。这是未定义的行为。

但是,在Java中就是这样。这是 Java 编程语言的规则。

Bitshift operators description in Java language specification

Weird result of Java Integer left shift

java : shift distance for int restricted to 31 bits

最佳答案

链接的问题明确指出,移位量大于被移位类型的位宽会调用 undefined behavior ,该标准将其定义为“使用不可移植或错误的程序构造或错误数据时的行为,本国际标准对此没有强加任何要求”

当您调用未定义的行为时,任何事情都可能发生。程序可能会崩溃,可能会输出奇怪的结果,或者看起来工作正常。此外,如果您使用不同的编译器或在同一编译器上使用不同的优化设置,未定义行为的表现方式也会发生变化。

C 标准在第 6.5.7p3 节中对位移运算符作了如下说明:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

在这种情况下,编译器可能会像您建议的那样减少以位宽为模的移位量,或者它可以将其视为数学上移位该量导致所有位为 0。两者都是有效结果,因为该标准未指定行为。

关于c - 为什么将变量移位超过其位宽度会清零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51145636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com