我正在尝试实现一个左旋转函数,将整数 x 左旋转 n 位
- 例如:rotateLeft(0x87654321,4) = 0x76543218
- 法律行动:~ & ^ | + >
到目前为止我有这个:
int rotateLeft(int x, int n) {
return ((x << n) | (x >> (32 - n)));
}
我已经意识到它不适用于有符号整数..有人知道如何解决这个问题吗?
所以现在我尝试了:
int rotateLeft(int x, int n) {
return ((x << n) | ((x >> (32 + (~n + 1))) & 0x0f));
}
并收到错误:
错误:测试旋转左(-2147483648 [0x80000000],1 [0x1])失败...
...给出 15[0xf]。应为 1[0x1]
目前编译器友好的轮换最佳实践是此社区维基问答 https://stackoverflow.com/questions/776508/circular-shift-rotate-operations-in-c。维基百科的代码不能用 clang 或 5.1 之前的 gcc 生成很好的 asm。
关于位旋转(又名循环移位)有一个非常好的、详细的解释维基百科 http://en.wikipedia.org/wiki/Circular_shift.
引用那里的内容:
unsigned int _rotl(const unsigned int value, int shift) {
if ((shift &= sizeof(value)*8 - 1) == 0)
return value;
return (value << shift) | (value >> (sizeof(value)*8 - shift));
}
unsigned int _rotr(const unsigned int value, int shift) {
if ((shift &= sizeof(value)*8 - 1) == 0)
return value;
return (value >> shift) | (value << (sizeof(value)*8 - shift));
在您的情况下,由于您无权访问乘法运算符,因此您可以替换*8
with << 3
.
EDIT您还可以删除if
给定您不能使用的声明的声明if
。这是一种优化,但即使没有它,您仍然可以获得正确的值。
请注意,如果您确实打算旋转位signed
整数,旋转结果的解释将取决于平台。具体要看平台是否使用补码 http://en.wikipedia.org/wiki/Two%27s_complement or 一个的补语 http://en.wikipedia.org/wiki/One%27s_complement。我想不出有哪个应用程序对有符号整数的位进行循环是有意义的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)