当你做这样的事情时,在C中:
char var = 1;
while(1)
{
var = var << 1;
}
在第8次迭代中,“&lt;&lt;&lt;运算符将移出1并且var将为0.我需要执行移位以保持位移位。换句话说,我需要这个:
首字母----- 00000001
第一班 - 00000010
第二班 - 00000100
第3班 - 00001000
第四班 - 00010000第5班 - 00100000
第6班 - 01000000
第7班 - 10000000
第8班 - 00000001(第8班,自动重新开始)
是否有相当于“&lt;&lt;”的东西但要实现这个目标吗?
答案 0 :(得分:5)
这称为circular shift,但C在语言级别不提供此功能。
你要么必须自己实现,要么采用内联汇编程序,假设你的平台本身就有这样的指令。
例如:
var = (var << 1) | (var >> 7);
(但这不适用于否定signed
类型,因此您必须将示例更改为unsigned char
。)
答案 1 :(得分:1)
是的,您可以使用circular shift。 (虽然它不是内置的C操作,但它在x86 CPU上是CPU instruction)
答案 2 :(得分:1)
所以你想做一点旋转,a.k.a。循环移位,然后。
#include <limits.h> // Needed for CHAR_BIT
// positive numbits -> right rotate, negative numbits -> left rotate
#define ROTATE(type, var, numbits) ((numbits) >= 0 ? \
(var) >> (numbits) | (var) << (CHAR_BIT * sizeof(type) - (numbits)) : \
(var) << -(numbits) | (var) >> (CHAR_BIT * sizeof(type) + (numbits)))
由于sizeof()
返回大小为char
(sizeof(char) == 1
)大小的倍数,CHAR_BIT
表示char
中的位数(虽然通常为8,但不一定是),CHAR_BIT * sizeof(x)
会以比特为单位给出x
的大小。
答案 3 :(得分:0)
这称为循环移位。有英特尔x86汇编指令要做到这一点,但除非性能真的是一个巨大的问题,你最好使用这样的东西:
int i = 0x42;
int by = 13;
int shifted = i << by | i >> ((sizeof(int) * 8) - by);
如果您发现自己确实需要性能,可以使用内联汇编直接使用说明(可能。我从来没有非常需要它来尝试)。
同样重要的是要注意,如果您要移动的位置超过数据类型的大小,则需要进行额外检查以确保不会过度移位。使用by = 48
可能会导致移位接收值为0,尽管此行为可能是特定于平台的(即可以像瘟疫一样避免),因为如果我没记错,某些平台会自动执行此屏蔽而其他平台则不会。