一篇文章徹底弄明白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的個數