目錄導引: 一、原碼、反碼、補碼 二、位運算 一、原碼、反碼、補碼 電腦只有加法運算器,計算器中存儲、計算數據都是補碼,正數和0的原碼、反碼、補碼相同,負數的原碼、反碼、補碼不同。 原碼:符號位+絕對值(0表示正數,1表示負數) 反碼:符號位不變,其餘位取反 補碼:反碼+1 1、為什麼要用補碼存儲 ...
目錄導引:
一、原碼、反碼、補碼
電腦只有加法運算器,計算器中存儲、計算數據都是補碼,正數和0的原碼、反碼、補碼相同,負數的原碼、反碼、補碼不同。
原碼:符號位+絕對值(0表示正數,1表示負數)
反碼:符號位不變,其餘位取反
補碼:反碼+1
1、為什麼要用補碼存儲,以及補碼計算?
因為原碼和反碼計算會出現+0 和 -0以及計算錯誤問題,而補碼是正確而簡單的,符號位也直接參与運算。
示例:
int是4位元組,1位元組是8位,所以一個int值是32位,第一位是符號位,所以int的取值範圍是 -2^31 ~ 2^31-1(10000000 00000000 00000000 00000000~01111111 11111111 11111111 11111111,該二進位是補碼)
分別計算 2+(-1)和1+(-1),過程如下:
2的原碼、反碼、補碼分別是 00000000 00000000 00000010,00000000 00000000 00000010,00000000 00000000 00000010
1的原碼、反碼、補碼分別是 00000000 00000000 00000001,00000000 00000000 00000001,00000000 00000000 00000001
-1的原碼、反碼、補碼分別是 10000000 00000000 00000001,11111111 11111111 11111111 11111110,11111111 11111111 11111111 11111111
2和-1原碼相加,結果為:10000000 00000000 00000011(原碼),0代表正數,1代表負數,所以值為-3,錯誤。
2和-1反碼相加,結果為:00000000 00000000 00000000(反碼),對應原碼的結果為00000000 00000000 00000000(原碼),值為0,錯誤。
2和-1補碼相加,結果為:00000000 00000000 00000001(補碼),對應原碼的結果為00000000 00000000 00000001(原碼),值為1,正確。
1和-1原碼相加,結果為:10000000 00000000 00000010(原碼),值為-2,錯誤。
1和-1反碼相加,結果為:11111111 11111111 11111111 11111111(反碼),對應原碼的結果為10000000 00000000 00000000(原碼),值為-0,不准確。(關於+0和-0的設計,有興趣可自行百度)
1和-1補碼相加,結果為:00000000 00000000 00000000(補碼),對應原碼的結果為00000000 00000000 00000000(原碼),值為0,正確。
二、位運算
位運算符包括: 與(&)、或(|)、非(~)、異或(^)、左移(<<)、右移(>>)、無符號右移(>>>)
&:二進位位同時為1時,結果為1,否則為0
| :位有一個為1時,結果為1,否則為0
~:位0變1,1變0
^:位不同時,結果為1,否則為0
<<:位整體向左移動,右邊補0
>>:位整體向右移動,正數左邊補0,負數左邊補1
>>>:位整體向右移動,左邊補0
示例:
public class BitOperationTest {
public static void main(String[] args) {
int a = 13, b = 6;
System.out.println(" a :" + getBinaryStr(a));
System.out.println(" b :" + getBinaryStr(b));
System.out.println(" a&b :" + getBinaryStr(a & b));
System.out.println(" a|b :" + getBinaryStr(a | b));
System.out.println(" ~a :" + getBinaryStr(~a));
System.out.println(" a^b :" + getBinaryStr(a ^ b));
System.out.println(" a<<b :" + getBinaryStr(a << b));
System.out.println(" a>>b :" + getBinaryStr(a >> (b - 4)));
System.out.println(" -a :" + getBinaryStr(-a));
System.out.println(" a>>>b:" + getBinaryStr(a >> (b - 4)));
System.out.println("-a>>>b:" + getBinaryStr((-a) >> (b - 4)));
}
private static String getBinaryStr(int n) {
StringBuilder str = new StringBuilder(Integer.toBinaryString(n));
int len = str.length();
if (len < 32) {
for (int i = 0; i < 32 - len; i++) {
str.insert(0, "0");
}
}
return str.substring(0, 8) + " " + str.substring(8, 16) + " " + str.substring(16, 24) + " " + str.substring(24, 32);
}
}
//Result
a :00000000 00000000 00000000 00001101
b :00000000 00000000 00000000 00000110
a&b :00000000 00000000 00000000 00000100
a|b :00000000 00000000 00000000 00001111
~a :11111111 11111111 11111111 11110010
a^b :00000000 00000000 00000000 00001011
a<<2 :00000000 00000000 00000000 00110100
-a :11111111 11111111 11111111 11110011
a>>2 :00000000 00000000 00000000 00000011
(-a)>>2 :11111111 11111111 11111111 11111100
a>>>2 :00000000 00000000 00000000 00000011
(-a)>>>2:00111111 11111111 11111111 11111100
如有疑問歡迎提出,如有錯誤歡迎指正。