3

In C when you do something like this:

char var = 1;

while(1)
{
  var = var << 1;
}

In the 8th iteration the "<<" operator will shift out the 1 and var will be 0. I need to perform a shift in order to mantain the bit shifting. In other words I need this:

initial ----- 00000001

1st shift -- 00000010

2nd shift - 00000100

3rd shift - 00001000

4th shift - 00010000

5th shift -- 00100000

6th shift -- 01000000

7th shift - 10000000

8th shift - 00000001 (At the 8th shift the one automatically start again)

Is there something equivalent to "<<" but to achieve this?

4

4 回答 4

5

This is known as a circular shift, but C doesn't offer this functionality at the language level.

You will either have to implement this yourself, or resort to inline assembler routines, assuming your platform natively has such an instruction.

For example:

var = (var << 1) | (var >> 7);

(This is not well-defined for negative signed types, though, so you'd have to change your example to unsigned char.)

于 2012-07-05T14:54:30.350 回答
1

是的,您可以使用循环移位。(虽然它不是内置的 C 操作,但它是x86 CPU 上的CPU 指令)

于 2012-07-05T14:55:14.457 回答
1

所以你想做一点旋转,也就是循环移位。

#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)))

Assizeof()返回大小为char( sizeof(char) == 1) 大小的倍数,并CHAR_BIT指示 a 中的位数char(虽然通常为 8,但不一定是),CHAR_BIT * sizeof(x)将为您提供x以位数为单位的大小。

于 2012-07-05T15:09:42.267 回答
0

这称为循环移位。有英特尔 x86 汇编指令可以做到这一点,但除非性能真的是一个巨大的问题,否则你最好使用这样的东西:

int i = 0x42;
int by = 13;
int shifted = i << by | i >> ((sizeof(int) * 8) - by);

如果您发现自己真的需要性能,您可以使用内联汇编直接使用指令(可能。我从来没有非常需要它来尝试)。

同样重要的是要注意,如果您要移动的位置超过数据类型的大小,则需要进行额外检查以确保不会过度移动。使用by = 48可能会导致 shift 接收值 0,尽管这种行为可能是特定于平台的(即像瘟疫一样要避免的事情),因为如果我没记错的话,一些平台会自动执行此屏蔽,而其他平台则不会。

于 2012-07-05T14:56:45.680 回答