3

我用 C 写了这个小代码:

int leftrotate (int x, int offset)
{
    return ( x << offset ) | ( x >> (32 - offset));
}

我期望二进制向左旋转一个整数,这意味着我期望将所有位从给定的偏移量移到左侧,如果数字太大,则进行滚球。

例如,当我输入:

10100110100110100101000011111101 = 2795131133 = a69a50fd

我期待作为回报:

01101001101001010000111111011010 = 1772425178 = 69a50fda

(请注意,开头的十六进制a现在位于结尾,因为我在此特定示例中选择了偏移量 4)

但相反,我得到了:

11111111111111111111111111111010 = 4294967290 = fffffffa
  • 有什么想法可以从哪里来或我做错了什么?
  • 我使用正确int吗?我应该uint改用吗?或者也许char
  • 这取决于我的计算机的体系结构(32 位还是 64 位)?
  • 我想这取决于整数的长度(这就是我使用 32 位长度数字的原因)?

谢谢 !!!

4

1 回答 1

6

它的实现定义了右移是算术移位还是逻辑移位。在您的情况下,它似乎是算术移位,因此您在>>表达式的一半中得到符号扩展。您需要进行强制转换unsigned或分配以获得您想要的行为。

unsigned int y = x;
return ( y << offset ) | ( y >> (32 - offset));

有什么想法可以从哪里来或我做错了什么?

由于右移有符号值而导致的符号扩展。

我使用正确的 int 吗?我应该改用 uint 吗?或者也许 char ?

在您的函数签名中更改为unsigned int可能是最简单的,是的。

这取决于我的计算机的体系结构(32 位还是 64 位)?

不,可能不是。

我想这取决于整数的长度(这就是我使用 32 位长度数字的原因)?

不,可能不是。但是,您可以使您的程序不依赖于整数的大小:

return (y << offset) | (y >> ((sizeof y * CHAR_BIT) - offset));
于 2013-09-11T18:08:00.010 回答