【问题标题】:how do I perform shifts in c without losing bits?如何在不丢失位的情况下在 c 中执行移位?
【发布时间】:2012-07-05 14:53:01
【问题描述】:

当你在 C 中做这样的事情时:

char var = 1;

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

在第 8 次迭代中,“

初始 ----- 00000001

第一班 -- 00000010

第二班 - 00000100

第三班 - 00001000

第四班 - 00010000

第 5 班 -- 00100000

第 6 班 -- 01000000

第 7 班 - 10000000

第 8 班 - 00000001(第 8 班自动重新开始)

有没有与“

【问题讨论】:

  • .asm { "ror Rx" }会不会是另一个方向的对应操作?

标签: c operators shift


【解决方案1】:

这称为circular shift,但 C 语言不提供此功能。

假设您的平台本机有这样的指令,您要么必须自己实现,要么求助于内联汇编程序。

例如:

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

(不过,这对于否定的 signed 类型没有明确定义,因此您必须将示例更改为 unsigned char。)

【讨论】:

    【解决方案2】:

    是的,您可以使用circular shift。 (虽然它不是内置的 C 操作,但它是 x86 CPU 上的CPU instruction

    【讨论】:

      【解决方案3】:

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

      #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 的大小(以位为单位)。

      【讨论】:

      • CHAR_BIT 是您正在寻找的内置宏。 :)
      【解决方案4】:

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

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

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

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

      【讨论】:

      • 必须是i &lt;&lt; by | i &gt;&gt; (sizeof(int)*8 - by)
      • :S 疱疹病毒。谢谢你说出我的意思。我会忘记的。顺便说一句,我在帖子中最常见的编辑原因是“笨蛋。我是个白痴”
      猜你喜欢
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-10
      • 2012-05-29
      • 1970-01-01
      • 2011-02-22
      相关资源
      最近更新 更多