循环移位c

时间:2012-11-08 12:48:54

标签: c

以下代码如何工作以及变量意味着什么:

y = (x << shift) | (x >> (sizeof(x)*CHAR_BIT - shift));

我在循环转换文章中找到了但没有解释它是如何工作的。

4 个答案:

答案 0 :(得分:25)

这是一种循环移位的方法。假设x是8位。

+----+----+----+----+----+----+----+----+
| x1   x2   x3   x4   x5   x6   x7   x8 |
+----+----+----+----+----+----+----+----+

然后,将它向左移动3给我们:

+----+----+----+----+----+----+----+----+
| x4   x5   x6   x7   x8    0    0    0 |
+----+----+----+----+----+----+----+----+

现在,CHAR_BIT*sizeof(x)与位数x的宽度相同,8。x向右移动8 - 3给了我们:

+----+----+----+----+----+----+----+----+
| 0    0    0    0    0    x1   x2   x3 |
+----+----+----+----+----+----+----+----+

接受你的OR:

+----+----+----+----+----+----+----+----+
| x4   x5   x6   x7   x8   x1   x2   x3 |
+----+----+----+----+----+----+----+----+

这在技术上是不可移动的,因为移动的数量等于类型的宽度是不可移动的 - 所以如果shift是8,那么左移是错误的,如果移位是0,那么正确的转变是错误的。但是,当按类型宽度移动时,这适用于所有三种常见行为。 (实际上,移位量会减少一些模数 - 或者是类型的位宽或更大的数字。)

它被称为循环移位或“旋转”,因为在左侧移出的位会向右移回。

复杂的编译器实际上会将代码编译为硬件循环指令。

答案 1 :(得分:18)

CHAR_BIT是每个字节的位数,应始终为8。

shift是您想要以循环方式向左移位的位数,因此向左移出的位返回右侧。

     1110 0000 << 2 results in:
     1000 0011

示例代码:

   y = (x << 2) | (x >> (8 - 2));

答案 2 :(得分:4)

(x << shift) 

向左移位“移位”位数,返回移出的位

(x >> (sizeof(x)*CHAR_BIT - shift));

为容纳这些位留出空间

CHAR_BIT是char中的位数,因此主要是8位。 在C中,您不是一次处理一个位,而是至少处理char位数。这就是你得到的粒度。

一般来说,

  

对于char,当你进行位旋转时,你会在8位字段(1字节)上进行

     

对于int,当你进行旋转时,你可以在32位字段(4字节)上进行


8位示例:

x = 11010101
shift = 2

x << (2) = 01010100 //shifted right by 2 bits

= x >> ((1 * CHAR_BIT) - 2)
= x >> (6) 
= 00000011 //shifted left by 6bits

OR这些按位提供

01010101
00000011
________
01010111

这是循环移位值2位

答案 3 :(得分:0)

这仅适用于无符号类型。在带符号的负数的情况下,大多数左位将被右移运算符(“&gt;&gt;”)

替换为最高有效位(1-s)的值。

我会这样写:

y = (x << shift) | ( (x >> (sizeof(x)*CHAR_BIT - shift)) & (0x7F >> (sizeof(x)*CHAR_BIT - shift) );

在此之前“|”运算符我们确认前n位(n = sizeof(x)* CHAR_BIT - 移位)归零。 我们还假设x很短(2个字节长)。所以,它也是类型依赖的。