2012-02-02 56 views
4

我想找到設置爲1的最高位。我已經盡一切可能從&到ORing從131的所有位,它不起作用。按位最重要的設置位

如果1000000我想要7

+1

那你詳細試試?結果是什麼? – 2012-02-02 18:28:21

+0

這是功課嗎? – 2012-02-02 18:36:11

+0

我做了所有的計數+ = 1&(〜x >> 1-31);它給了我不同的數字,而不是我期望的我想要的最重要的位是1,那就是 – mkuk 2012-02-02 18:36:34

回答

3

,你可以試試這樣的:

private int mostSignificantBit(int myInt){ 
    int mask = 1 << 31; 
    for(int bitIndex = 31; bitIndex >= 0; bitIndex--){ 
    if((myInt & mask) != 0){ 
     return bitIndex; 
    } 
    mask >>>= 1; 
    } 
    return -1; 
} 

我們將掩碼初始化爲1 << 31,因爲它表示1後跟31 0。我們使用該值來測試索引31(第32個點)是否爲1.當我們and這個值與myInt,我們得到一個0,除非對應的位設置在myInt。如果是這種情況,我們將返回​​。如果不是,那麼我們將面具向右移1並再試一次。我們重複,直到我們沒有地方轉移,在這種情況下,這意味着沒有設置位(也許你想拋出一個異常,而不是返回-1)。

注意這將返回值016641000000二進制)。如果你願意,你可以調整。還請注意,我使用了無符號右運算符而不是有符號右移。這是因爲這裏的意圖是處理原始位而不是它們的符號解釋,但在這種情況下並不重要,因爲在移位發生之前,所有負值將在循環的第一次迭代中終止。

+0

實際上使用未經簽名的右移運算符很重要。如果'myInt'不是負數,那麼你需要移動'mask'並且它開始爲負值。 – 2012-02-02 20:47:02

+0

如果使用帶符號的右移,'mask'將始終有一個不屬於的前導1(因爲'mask'開始爲負數),你是正確的。然而,這並不影響我的實現的結果,因爲當myInt不是負數時,多餘的1位總是被0和0(即myInt的符號位,我們剛剛說的是正)。 – 2012-02-02 21:26:23

+0

好點!我沒有完成在'mask'中領先1的後果,正如你指出的那樣,這完全不是什麼。 – 2012-02-02 23:05:15

-2
if(value | 0x40) return 7; 
else if(value | 0x20) return 6; 
else if(value | 0x10) return 5; 
else if(value | 0x8) return 4; 
else if(value | 0x4) return 3; 
else if(value | 0x2) return 2; 
else if(value | 0x1) return 1; 
+3

返回8到31發生了什麼? – 2012-02-02 18:38:29

0

不是最有效的,也許,但是這應該工作::

public int firstBit(int i) { 
    return i < 0 ? 31 : i == 0 ? 0 : Integer.toString(i, 2).length(); 
} 
-1

如果你堅持使用直接位操作只需添加另一種方法

public static int mostSignificantBit(int b) { 
    for (int i = 1 << 30, j = 0; i > 0; i /= 2, j++) { 
      if ((b & i) > 0) { 
      return 31-j; 
     } 
    } 
    return -1; 
} 
+0

您可能想要輸入「int」而不是「byte」。 – 2012-02-02 19:19:54

+0

@MichaelMcGowan,是的,謝謝 – 2012-02-02 19:21:18

+0

我不認爲你的出發點是正確的。此代碼爲「Integer.MAX_VALUE」提供了與負數相同的答案。 – 2012-02-02 19:26:10

1

逐次逼近將迭代儘量減少五個環:

unsigned int mostSignificantBit(uint32_t val) { 
    unsigned int bit = 0; 

    /* 4 = log(sizeof(val) * 8)/log(2) - 1 */ 
    for(int r = 4; r >= 0 ; --r) { 
    unsigned shift = 1 << r; /* 2^r */ 
    uint32_t sval = val >> shift; 
    if (sval) { 
     bit += shift; 
     val = sval; 
    } 
    } 
    return bit; 
} 
6

雖然有接受一個答案,我有另一種方式來分享我認爲這是比較容易。

如果你想使用按位運算,這裏是方法。基本上,我正確地移動整數直到它變成零。沒有掩碼是必需的。

private static int mostSignificantBit(int myInt){ 
    int i = 0; 
    while (myInt != 0) { 
     ++i; 
     myInt >>>= 1; 
    } 
    return i; 
} 

另一種方法是數學計算的話:

private static int mostSignificantBit(int myInt){ 
    if (myInt == 0) return 0; // special handling for 0 
    if (myInt < 0) return 32; // special handling for -ve 

    return (int)(Math.log(myInt)/Math.log(2)) +1; 
} 
4

靈巧實現我遇到 - 三次迭代和查表。

unsigned int msb32(unsigned int x) 
{ 
    static const unsigned int bval[] = 
    { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; 

    unsigned int base = 0; 
    if (x & 0xFFFF0000) { base += 32/2; x >>= 32/2; } 
    if (x & 0x0000FF00) { base += 32/4; x >>= 32/4; } 
    if (x & 0x000000F0) { base += 32/8; x >>= 32/8; } 
    return base + bval[x]; 
} 
1

只需使用Long或Integer類的numberOfTrailingZeros(value)方法。

0

小端格式:

((yourByte & yourBitMask) >> msbIndex) && 0x01