Java中的位運算及簡單的算法應用介紹

衆所周知,計算機底層是二進制。而java作爲一門計算機編程語言,也對二進制的位運算提供了完整的支持。

在java中,int是32位的,也就是說可以用來實現32位的位運算。方便起見,我們一般用16進制對它賦值,比如: 0011表示成16進制是 0x3, 110111表示成16進制是 0x37。

那麼什麼是位運算呢?位運算是將數據看做二進制,進行位級別的操作。主要有移位運算和邏輯運算

移位運算:

  • 左移:操作符爲<<,向左移動,右邊的低位補0,左邊高位捨棄,將二進制看做整數,左移1位就相當於乘以2。
  • 無符號右移:操作符爲>>>,向右移動,右邊的捨棄掉,左邊補0。
  • 有符號右移:操作符爲>>,向右移動,右邊的捨棄掉,左邊補的值取決於原來最高位,原來是1就補1,原來是0就補0,將二進制看做整數,右移1位相當於除以2。

10進制轉二進制的時候,因爲二進制數一般分8位、 16位、32位以及64位 表示一個十進制數,所以在轉換過程中,最高位會補零。

在計算機中負數採用二進制的補碼錶示,10進制轉爲二進制得到的是源碼,將源碼按位取反得到的是反碼,反碼加1得到補碼

二進制的最高位是符號位,0表示正,1表示負。

例如:

        int a = 4; //100
        a = a >> 2; //001,
        System.out.println("4>>2運算的結果是 :" + a);//變爲1
        a = 4; //100
        a = a << 3; //100000,
        System.out.println("4<<3運算的結果是 :" + a);//變爲32

        System.out.println("16>>2運算的結果是 :" + ((16) >> 2));//變爲4
        System.out.println("-16>>2運算的結果是 :" + ((-16) >> 2));//變爲-4
        System.out.println("16>>>2運算的結果是 :" + ((16) >>> 2));//變爲4
        System.out.println("-16>>>2運算的結果是 :" + ((-16) >>> 2));//變爲大的整數,看是多少位的

得到結果

 

可見正數做>>>運算的時候和>>是一樣的。區別在於負數運算.

 

邏輯運算有:

  • 按位與 &:兩位都爲1才爲1
  • 按位或 |:只要有一位爲1,就爲1
  • 按位取反 ~: 1變爲0,0變爲1
  • 按位異或 ^ :相異爲真,相同爲假

例如:

int a = ...; 
a = a & 0x1 // 返回0或1,就是a最右邊一位的值。
a = a | 0x1 //不管a原來最右邊一位是什麼,都將設爲1

我們來看幾個簡單的應用場景:

場景一:判斷奇偶

分析:奇數都不是2的整數倍,轉換成二進制後最低位必然爲1,偶數則相反。利用這個特性我們可以很容易的通過位運算判斷一個整數的奇偶性。

看代碼:

    int i = 1;// 二進制存儲方式爲00000000000000000000000000000001
    int j = 5;// 二進制存儲方式爲00000000000000000000000000000101
    int k = 6;// 二進制存儲方式爲00000000000000000000000000000110
    if ((i & j) == 1) {
      System.out.println("j的最低位爲1,爲奇數");
    }
    if ((i & k) == 0) {
      System.out.println("k的最低位爲0,爲偶數");
    }

場景二:判斷一個正整數是不是2的整數次冪

分析:我們先來看一下常見的2的整數次冪的數:2、4、8、16,轉化成二進制依次爲:10、100、1000、10000,發現規律了沒有?那就是除了首位是1,其他全是0。恰巧這些數減去1後等於他們依次按位取反的結果,比如8-1=7,二進制是111,可以通過8的二進制1000按位取反得到。而8&7=0,提取一下規律就是:

(n&(n-1))==0

符合這個規律的n就是2的整數次冪了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章