【发布时间】:2015-07-05 08:10:27
【问题描述】:
这里有很多关于循环位移行为的问题;然而,即使在经历了这些之后,我认为下面的陈述没有被任何人提出,我对此感到有点困惑。
来自维基百科的Circular Shift 声明:
/* * Shift operations in C are only defined for shift values which are * not negative and smaller than sizeof(value) * CHAR_BIT. */ unsigned int rotl(unsigned int value, int shift) { return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift)); } unsigned int rotr(unsigned int value, int shift) { return (value >> shift) | (value << (sizeof(value) * CHAR_BIT - shift)); }
我对上面几行的解释是——在上面提到的两个换档行为条件下是不确定的。
但是我看到给出的例子
rotl(0x8000, -1) 回复0x00010000。
rotl(8,-1) 回复16。
处理此类移位参数(即负数和大于位数)的正确方法是什么?我是不是误解了什么?
【问题讨论】:
-
第二个例子与第一个例子相矛盾。我认为第二个函数调用的结果应该是 16 而不是 4。
-
@VladfromMoscow - 是的,我编辑了答案 - 但我已将示例作为参考 - 我的主要困惑点是部分 - 根据该部分,如果移位值为 -ve - 行为应该未定义 -你能帮我理解吗?
-
如果进行右移(
>>),RHS 上的值必须介于 0 和值中的位数减一之间;如果您进行左移,则 RHS 上的值必须介于 0 和值中的位数减一之间。因此,您可以将一个方向定义为正方向,将另一个方向定义为负方向,并通过一个函数调用来管理它们,该函数调用接受一个正参数或负参数,并通过适当的移位操作将负值转换为正值。看起来rotl函数希望负值向左移动——这是一个合理但随意的选择。 -
...既然代码添加到问题中,很容易看出维基百科上
rotl()的版本只能合法调用shift的值在0到31之间(如果unsigned int是 32 位值)。任何用负值调用它的尝试都会导致未定义的行为。您没有显示使用负转移的示例从哪里获得 - 它似乎不是维基百科。可能有一个rotl的实现,它测试shift的值是正还是负,并使用rotl()和rotr()中显示的表达式中的一个或另一个来实现所需的结果。 -
@JonathanLeffler - 实际上注意到我指的是直接显示答案 - 但我想你的答案和为模运算提供的其他答案我明白当 shift 的值是这两个条件之一时该怎么做 -感谢您的帮助
标签: c bit-manipulation bit-shift