2015-09-14 139 views
2

下面兩個代碼是該方法可以反轉無符號32位整數的位。但是下面兩個代碼有什麼區別? 爲什麼第一個代碼是錯誤的,第二個代碼是正確的。 我看不出這兩者的區別。無符號整數的反向位

public int reverseBits(int n) { 
    int result = 0; 
    for (int i = 0; i < 32; i++) { 
     result = result << 1 | (n & (1 << i)); 
    } 
    return result; 
} 
public int reverseBits(int n) { 
    int result = 0; 
    for (int i = 0; i < 32; i++) { 
     result = result << 1 | ((n >> i) & 1); 
    } 
    return result; 
} 

感謝您的幫助。

回答

0

第一個代碼是錯誤的,因爲它提取給定位並將其放在結果數字的相同位置。假設您正在迭代i = 5。然後n & (1 << 5) = n & 32這是0或0b100000。意圖是將1位置於最低位置,但在執行|時它實際上將它放到了#5的相同位置。在隨後的迭代中,您將該位移動得更高,因此實際上將所有位或位置設置爲最高位。

請注意,有扭轉像一個在標準JDK Integer.reverse方法來實現比特更有效的算法:

public static int reverse(int i) { 
    // HD, Figure 7-1 
    i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555; 
    i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333; 
    i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f; 
    i = (i << 24) | ((i & 0xff00) << 8) | 
     ((i >>> 8) & 0xff00) | (i >>> 24); 
    return i; 
} 
0

它與從n中抓取的位是存儲在結果的最右邊位還是存儲回相同的位置有關。

0

假設n是4(例如)。 然後,當i是2時,表達(n & (1 << i)) 變得(4 & (1 << 2)),這應該等於4 & 4,所以它的計算結果爲4. 但表達((n >> i) & 1) 變得((4 >> 2) & 1),其應該等於1 & 1,所以它的計算結果爲1

的兩個表達式不具有相同的結果。

但是,函數的兩個版本都嘗試以完全相同的方式使用這些結果,所以函數的兩個版本沒有相同的結果。