使用左移和右移的组合可以进行旋转。
移位有一个问题,那就是有符号整数的符号位会受到影响。建议先转换为unsigned
类型再进行移位操作。@The Paramagnetic Croissant
实现定义的行为示例是:当带符号整数向右移位时,高位比特的传播方式。
向左或向右移超过位宽的比特也会导致问题。应将实际移位限制为n mod Bit_width
。 当n == 0
时,OP的(...<<(32-n));
代码存在问题。
OP的示例看起来更像是左旋转。我们假设该函数应该是向右旋转。(0x87654321,4)
--> 0x18765432
。 @Mark Shevchenko
int
的宽度可能不是32位。
#include <limits.h>
#define INT_BIT_WIDTH (sizeof (int) * CHAR_BIT)
int rotateRight(int x, int n) {
unsigned xu = x;
unsigned nu = n;
nu %= INT_BIT_WIDTH;
unsigned y = xu >> nu;
if (nu > 0) {
y |= xu << (INT_BIT_WIDTH - nu);
}
return y;
}
[编辑]由于原帖仅限使用 ~ & ^ | + << >>
,请使用以下替代代码。
注意:这是一个罕见的问题,在int
的宽度不是2的幂的情况下出现。
// nu %= INT_BIT_WIDTH;
nu &= INT_BIT_WIDTH - 1;
[编辑2] 我想出一个受@RPGillespie启发的无符号
简约解决方案,因为OP无法使用%
。
#include <limits.h>
#define UNS_WIDTH (sizeof (unsigned) * CHAR_BIT)
#define UNS_WIDTH_M1 (UNS_WIDTH - 1)
unsigned unsigned_rotate_right(unsigned x, unsigned n) {
return (x >> (n & UNS_WIDTH_M1)) | (x << ((UNS_WIDTH - n) & UNS_WIDTH_M1));
}
unsigned
,然后你就可以继续进行了。 - The Paramagnetic Croissant%32
的详细信息 - 是否应该尝试修复:some_int%32
不是返回0-31的模运算,而是C余数操作符,在这种情况下返回-31到31。some_int%32u
将为所有int
编码实现“安全”缩减。 - chux - Reinstate Monica