1. 程式人生 > >一篇文章徹底弄明白java中的二進位制運算

一篇文章徹底弄明白java中的二進位制運算

在java中的二進位制運算子有:<<(左移保留符號位), >>(右移保留符號位), >>>(右移,符號位也一起移動), ~(按位取反), ^(異或,相同為0,不同為1), &(邏輯與) ,|(邏輯或),下面我們就來一個一個解釋一下。

在說二進位制運算之前,我們先來了解一下原碼,反碼和補碼的概念:

原碼:第一位是符號位,0表示正數,1表示負數。其餘31位為具體的值,例如:

10的原碼:00000000000000000000000000001010;

-10的原碼:10000000000000000000000000001010;

反碼:在原碼的基礎上,符號位不變,其餘的按位取反,例如:

10的反碼:11111111111111111111111111110101; //在java中沒有用到

-10的反碼:11111111111111111111111111110101;

補碼:負數的補碼就是反碼+1,整數的補碼就是原碼本身

10的補碼:00000000000000000000000000001010;

-10的補碼:11111111111111111111111111110110;

在java中整數是用補碼來表示的,記住正數的補碼就是原碼本身,負數的補碼是反碼+1

@org.junit.Test
    public void test5() {
        int a = 10;
        int b = -10;
        System.out.println(Integer.toBinaryString(a)); //1010;toBinaryString方法會省略掉前面的0
        System.out.println(Integer.toBinaryString(b));//11111111111111111111111111110110;確實是反碼+1
    }

接下來我們來說二進位制移位運算:

value << N :保留符號位,其餘的向左移動N位,整數和負數都是低位補0,相當於乘以2的N次方,這種方式用來做2的整數倍乘法運算效率很高。

>>:保留符號位,其餘的向右移動N位,整數高位補0,負數高位補1;

>>>:將符號位也一起移動,高位補0,正數跟>>一樣,負數因為符號位是1,移動後的結果可能不是我們預期的,

請認真看一下下面的例子:

@org.junit.Test
    public void test6(){
        int a = 10; //00000000000000000000000000001010
        int b = -10; //11111111111111111111111111110110
        System.out.println(a << 2); //40,00000000000000000000000000101000,相當於乘以4
        System.out.println(b << 2); //-40,11111111111111111111111111011000,相當於乘以4
        System.out.println(a >> 2); //2,00000000000000000000000000000010,正數向左移動後,高位是補0,跟符號位一致
        System.out.println(b >> 2); //-3,11111111111111111111111111111101,負數向左移動後,高位時補1,跟符號位一致
        System.out.println(a >>> 2); //40,00000000000000000000000000101000,相當於乘以4
        System.out.println(b >>> 2); //1073741821,00111111111111111111111111111101,將符號位也一起向右移動,高位補0,所以負數會變成一個正數。
    }

接下來我們來說一下二進位制的邏輯運算:

&:按位邏輯與,都為1則為1,否則為0;

|:按位邏輯或,都為0則為0,有一個為1則為1;

~:按位取反,包括符號位

請看下面的例子:

    @org.junit.Test
    public void test7(){
        int a = 10; //00000000000000000000000000001010
        int b = 9; //00000000000000000000000000001001
        System.out.println(a & b); //8,00000000000000000000000000001000,都為1則為1,否則為0
        System.out.println(a | b); //11,00000000000000000000000000001011,只要有一個為1就為1
        System.out.println(a ^ b); //3,00000000000000000000000000000011,相同為0,不同為1
        System.out.println(~a); //-11,11111111111111111111111111110101,按位取反
    }

以上就是java中的二進位制運算,記得以前有一道筆試題,輸入兩個int的整數a,b,求他們的二進位制表示中有多少位相同?

當時想了好久,都沒搞定,看完二進位制的運算後就變得很簡單了,只要用到Integer中提供的bitCount靜態方法就可以了,請看:

public void test8() {
        int a = 11; //00000000000000000000000000001011
        int b = 3; //00000000000000000000000000000011
        int count = Integer.bitCount(11 & 3); //預期是2,返回是2
        System.out.println(count);
    }

PS:toBinaryString:返回整數的二進位制表示,從第一個不為0的位開始,會省略前面的0

         bitCount:返回二進位制中1的個數