1. 程式人生 > 實用技巧 >b&0xF 與 b是什麼關係

b&0xF 與 b是什麼關係

轉載自:https://blog.csdn.net/u013513053/article/details/104674801/

今天同事看到一行程式碼

if ((d2[i] & 0x0F) == 0x0F || (d2[i] & 0xF0) == 0xF0){
//省略
}

然後就很奇怪這個運算,一個數值與上 0x0F,判斷是否等於0x0F。那麼這個數值與 0xF不就是數字本身麼?為啥要多此一舉呢?
我試驗了一下,的確

1 & 0x0F = 1
10 & 0x0F = 10
15 & 0x0F = 15

這麼看的確是很困惑,如果這樣的話,為啥不直接判斷d2[i] == 0x0F這樣呢?

負數操作

我印象中好像我也這麼幹過,但是太久遠了一直想不起來為啥。我就去查資料。但是百度出來的也沒說出所以然,我忽然想了起來,負數與之後也是這樣麼?

我用-1做實驗,果然結果是不一樣的。
-1 & 0x0F = 15
-10 & 0x0F = 6
-15 & 0x0F = 1

這是為什麼呢?
java中的幾個規則:

  1. Java中byte的大小是8bits,int的大小是32bits,byte的範圍是[-128,127],int的範圍是[-231,231-1]。

  2. Java中數值的二進位制是採用補碼的形式表示的。

byte 的長度是有限的,最大是127,那麼對於十六進位制的FF怎麼辦呢?我們經常要儲存十六進位制的數字,而十六進位制一位最大值FF 就是255,byte肯定超限了。java也是很貼心的給出瞭解決,0-127直接表示就可以,128也就是 0x80,就用負數表示,值為-128。值從負值遞增,129就是-127,130就是-126依次類推。,-1 到最大 255,也就是0xFF。

那麼從byte中取出來16進位制數怎麼辦,那就用byte 值與上 0xFF。注意這裡是0xFF。

這樣就可以理解了,-1其實不是-1,而是十六進位制0xFF。所以用-1&0x0F的結果就相當於 0xFF&0x0F。

然而結束了麼?並沒有

& 操作

上面例子測試只到了15,我們繼續把數值調大試一下
16 & 0x0F = 0
17 & 0x0F = 1

這裡又得說一下 & 操作符的意思。很簡單,就一句話

全部為1則為1,有一位0則為0

這裡是二進位制的位,每一位進行比較操作,全部為1則為1,有一個為0則為0。這麼說可能不太明白,舉個例子就好了

8 & 1

轉換為二進位制(二進位制轉換就不多說了)
1000&1

補位,不足的前面補0。這裡1前面需要補足
1000&0001

計算,全部為1的為 1 ,有0的為 0
每一位分別是
1&0 = 0
0&0 = 0
0&0 = 0
0&1 = 0
最終為
0000
結果為 0

這是原理,但是相信解釋原理即使明白了,實際運用也是困難的。誰閒著沒事轉二進位制計算?數字小還可以,要是數字大呢?算去吧

這裡我們找找有沒有簡便的方法或者規律,我們不妨多些幾個看看

1&1 = 1
2&1 = 0
3&1 = 1
4&1 = 0

2&2 = 2
3&2 = 2
4&2 = 0
5&2 = 0
6&2 = 2
7&2 = 2
8&2 = 0
9&2 = 0

3&3 = 3
4&3 = 0
5&3 = 1
6&3 = 2
7&3 = 3
8&3 = 0
9&3 = 1
10&3 = 2

我們可以發現一些結論

    1. 一個數&自身等於這個數自身
    2. 奇數&1等於1,偶數&1 =0。我們可以利用這個來判斷奇偶(運算速度比取餘快)
    3. 清零。如果想將一個單元清零,即使其全部二進位制位為0,只要與一個各位都為零的數值相與,結果為零。
    4. 取一個數中指定位
      方法:找一個數,對應X要取的位,該數的對應位為1,其餘位為零,此數與X進行“與運算”可以得到X中的指定位。
      例:設X=10101110,
      取X的第4位,用 X & 0000 1111 = 0000 1110即可得到;
      還可用來取X的2、4、6位。