說說Java 位運算

本文首發於我的微信公衆號《andyqian》,期待你的關注程序員

前言
咱們都知道,在計算機世界裏,再複雜,再美的程序,到最後都會變成0與1。也就是咱們常說的:二進制。二進制相信你們都很熟悉。與現實世界不一樣的是,在現實世界裏,咱們一般都是用十進制來表示的,也就是遇十進一,這些都是咱們熟悉的。到這裏,咱們就會發現端倪,現實世界中的十進制與計算機中的二進制其計量單元是不同的。那它們之間怎麼轉換呢?這就涉及到一些比較基礎的計算機知識。不在本文中討論(若是有興趣,能夠在下次講講)。嗯,回到今天的主題,來講說位運算,這又是一個怎樣的概念呢?咱們從小就開始接觸,現實世界中的加減乘除這些運算,也就是十進制中的運算。今天咱們要說的是:二進制位中的一些經常使用運算。例如:& (位與),| (位或) ,^(異或),<<(左移),>>(右移) 等等。算法

真與假
在進行運算符使用以前,咱們有必要說下真假。在Java中,咱們都知道,用 true 值表示真,false 值表示假。其實在計算機中,一般使用 1 表示真,0表示假。使用過Json的同窗應該知道,Java中的boolean類型,用1也是能夠反序列化成true,0反序列化爲false的。微信

& (位與)
在說位與以前,咱們先來講說咱們熟悉的 && 邏輯與操做。簡單來講: A&&B 也就是:A且B同時成立時爲真,不然爲假。也有人稱之爲:「一假必假」。spa

如今咱們再來看位與。首先,咱們來看一段程序:code

@Test源碼

public void testBit(){
    int a = 8;
    int b = 9;
    System.out.println("a binary: "+Integer.toBinaryString(a));
    System.out.println("b binary: "+Integer.toBinaryString(b));
    System.out.println("a & b binary: "+Integer.toBinaryString(a&b));
    System.out.println("a & b result: "+(a&b));
}

再看解釋以前,咱們先猜猜結果是多少?it

代碼解釋:class

位與:咱們從字面意思上來理解,也是二進制位的與操做。test

數字 8 的十進制是: 1000 。基礎

數字 9 的十進制是: 1001。

咱們再來進行位於操做:

以下所示:

8:1000
9:1001
&
8 1000

最左邊的 1&1 = 1,中間的 0&0 = 0,最右邊的0&1 = 0。

二進制的結果爲:1000,轉換爲10進制後爲 8。

程序運行結果以下:

a binary: 1000
b binary: 1001
a & b binary: 1000
a & b result: 8

結果是符合預期的。

| (位或)

上面說 & (位與) 操做,如今咱們來看看位或操做,繼續使用上面的例子:以下所示:

@Test

public void testBit(){
    int a = 8;
    int b = 9;
    System.out.println("a binary: "+Integer.toBinaryString(a));
    System.out.println("b binary: "+Integer.toBinaryString(b));
    System.out.println("a & b binary: "+Integer.toBinaryString(a|b));
    System.out.println("a & b result: "+(a|b));
}

再看看二進制:

8:1000
9:1001
|
9 1001
最左邊的 1|1 = 1,中間的0|0 = 0 ,最右邊的 0|1 = 1。

結果二進制爲: 1001 對應的10進製爲 9。

運算結果以下:

a binary: 1000
b binary: 1001
a & b binary: 1001
a & b result: 9

^(異或)

這個運算符比較有意思,異從字面上來理解是:不一樣的。放在位操做裏也是同樣的。繼續使用上面的例子:

@Test

public void testBit(){
    int a = 8;
    int b = 9;
    System.out.println("a binary: "+Integer.toBinaryString(a));
    System.out.println("b binary: "+Integer.toBinaryString(b));
    System.out.println("a & b binary: "+Integer.toBinaryString(a^b));
    System.out.println("a & b result: "+(a^b));
}

繼續看二進制:

8:1000
9:1001
^
1 0001

位相同時取假,不一樣時取真。左邊的 1=1 相同取假,也就是0。中間的0=0 也爲假爲0。最右邊的0不等於1,爲真。結果也就爲1。

<<(左移)

在現實世界裏,咱們常常使用乘法。<< 則表示二進制中的位移操做,低位補0。例如:8<<1。

@Test

public void testCode(){
    int a =8;
    System.out.println("a toBinaryString: "+Integer.toBinaryString(a));
    System.out.println("a<<1 toBinaryString: "+Integer.toBinaryString(a<<1));
    System.out.println("result: "+(a<<1));

二進制以下:

8 1000
8<<1
16 10000

結果爲: 2^4 = 16。 << 左邊 a 表示基數, 右邊 1 則表示須要位移動的位數。 箭頭指向哪邊,則向哪邊位移。程序運行結果:

a toBiryString: 1000
a<<1 toBinaryString: 10000
result: 16

>> 右移

(右移) 與左移 << 則是相反的,高位補0 。繼續上面的例子:

@Test

public void testCode(){
    int a =8;
    System.out.println("a toBinaryString: "+Integer.toBinaryString(a));
    System.out.println("1>>a toBinaryString: "+Integer.toBinaryString(a>>1));
    System.out.println("result: "+(a>>1)
}

二進制:

8 : 1000
8>>1
4 : 0100

運行結果:

a toBinaryString: 1000
a>>1 toBinaryString: 100
result: 4

其實這裏還有一個比較好記的口訣:

a>>n 則表示: a / (2^n) 次方。 (取整)

a<<n 則結果爲: a * (2^n) 次方。

如今咱們來速算一下:

當a = 13, n = 2 時。13<<2 等於 13* 4 = 52 。 13/4 = 3。

(上述速算法,若有錯誤,歡迎打臉!!!)


咱們在源碼以及常見算法中位移運算是很是常見的,一位Java程序員掌握位運算也是頗有必要的。這對咱們算法,源碼理解都很是有幫助!


相關閱讀:

《上千行存儲過程有感!》

《軟件之路》

《淺談 Java JPDA》

《說說MySQL權限》

<center></center>

相關文章
相關標籤/搜索