2012-11-08 50 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字節長)。所以,它也是類型依賴的。