2012-11-08 52 views
25

如何将下面的代码工作和做什么的变量的含义:循环移位

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

我在一个循环移位文章,但对如何工作没有解释发现。

回答

16

CHAR_BIT是每个字节的位数,应该总是8位。

shift是您想要以循环方式向左移位的位数,所以左移的位回到右边。对于示例

 1110 0000 << 2 results in: 
    1000 0011 

代码:

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

如果我想要使用位数为10位的数字前1111101010来转换数字,那么CHAR_BIT是10或者我错了? – user1809300

+0

CHAR_BIT始终是8 – thumbmunkeys

+2

CHAR_BIT始终为8,适用于任何在21世纪将使用的健全架构:-) – xanatos

3
(x << shift) 

位移它移'比特向左的数,返回移出位

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

使空间用于容纳那些位

CHAR_BIT是字符中的位数,所以大多数是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位

+0

我有一个问题:当我使用<<命令10101它给1010100而不是10100为什么? – user1809300

+0

@ user1809300这是因为8位粒度。 '10101'是'00010101'。上面的例子并不直接适用于C.它只是说明它是如何工作的。在C/C++中,你一次可以处理8位字符。 –

+0

以及它如何可以给10100? – user1809300

22

这是执行循环移位的方法。假设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。因此,通过8 - 3转移x到右侧给我们:

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

,并采取或者你会:

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

这在技术上是不可移植的,因为它是不可移植的量等于转向到类型的宽度 - 所以如果移位是8,那么左移是错误的,并且如果移位是0,则右移是错误的。然而,当按类型宽度移动时,这在所有三种常见行为的实践中都有效。 (实际上,移位量减少了一些模 - 无论是类型的位宽还是一些较大的数)。

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

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

+2

+1,但8不是一个很好的例子它是不确定的,因为按照通常的算术转换,移位类型至少是(有符号或无符号)“int”,而“int”至少是16位。 –

0

这只适用于无符号类型。在带符号负数的情况下,最左边的位将由右移运算符(“>>”)用最高有效位(1-s)的值代替

我会这样写:

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

在这里之前“|”我们确认前n位(n = sizeof(x)* CHAR_BIT - shift)为零。我们还假设x很短(2字节长)。所以,它也是类型依赖的。