如何在不丢失位的情况下执行c的移位?

时间:2012-07-05 14:53:01

标签: c operators shift

当你做这样的事情时,在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;”的东西但要实现这个目标吗?

4 个答案:

答案 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()返回大小为charsizeof(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,尽管此行为可能是特定于平台的(即可以像瘟疫一样避免),因为如果我没记错,某些平台会自动执行此屏蔽而其他平台则不会。