1.簡介
二進制是計算機技術中廣泛采用的一種數制。二進制數據是用0和1兩個數碼來表示的數。它的基數為2,進位規則是“逢二進一”,借位規則是“借一當二”,由17世紀至18世紀的德國數學家萊布尼茲提出。在計算機中,所有的數據都是以0和1的形式存在的,比如CPU,內存,硬盤中的數據都是“0”和“1”。也就是說二進制只能有0、1;八進制為:0-7;十進制:0-9;十六進制比較特殊為:0-9,A(10) B(11) C(12) D(13) E(14) F(15)
2.二進制原碼、反碼、補碼
(1)原碼
所謂原碼就是機器數,是加了一位符號位的二進制數(因為數值有正負之分),正數符號位為0,負數符號位為1。計算機中存儲、處理、運算的數據通常是8位、16位、32位或64位的。
示例如下:
public class Test{ public static void main(String[] args) { System.out.println(toUnsignedString(10)); System.out.println(toUnsignedString(-10)); } final static char[] digits = {'0' , '1'}; /**獲取原碼方法,int類型32位,為了方便查看,所以循環32次 */ private static String toUnsignedString(int value) { StringBuilder sb = new StringBuilder(); int i = 32; int j = value; do { if (j >= 0) sb.insert(0,digits[j % 2]); else sb.insert(0,digits[-(j % 2)]);//因為小於0,所以得出的數值為負數,加上負號轉為正數 j /= 2; i--; } while (i > 0); //格式處理一下 if(value < 0) sb.setCharAt(0, '1'); for (i = 0; i < sb.length(); i++) { if((i + 1) % 5 == 0) sb.insert(i, " "); } return sb.toString(); } }
運行結果
0000 0000 0000 0000 0000 0000 0000 1010
1000 0000 0000 0000 0000 0000 0000 1010
通過上面的案例,可以很清晰的看到二進制位的首位標識該二進制數是一個正數還是負數,其他的為真值的絕對值。
(2)反碼
所謂反碼就是在原碼的基礎上,符號位不變其他位按位取反(就是0變1,1變0)就可以了。
示例如下:
public class Test{ public static void main(String[] args) { System.out.println(toUnsignedString(10)); System.out.println(toUnsignedString(-10)); } final static char[] digits = {'0' , '1'}; /**獲取原碼方法,int類型32位,為了方便查看,所以循環32次 */ private static String toUnsignedString(int value) { StringBuilder sb = new StringBuilder(); int i = 32; int j = value; do { if (value > 0 && j >= 0) sb.insert(0,digits[j % 2]); else sb.insert(0,digits[-~(j % 2)]);//因為小於0,所以得出的數值為負數,加上負號轉為正數 j /= 2; i--; } while (i > 0); //格式處理一下 if(value < 0) sb.setCharAt(0, '1'); for (i = 0; i < sb.length(); i++) { if((i + 1) % 5 == 0) sb.insert(i, " "); } return sb.toString(); } }
運行結果
0000 0000 0000 0000 0000 0000 0000 1010
1111 1111 1111 1111 1111 1111 1111 0101
通過上面的案例,可以很清晰的看到正數的反碼 == 原碼,負數的反碼是在其原碼的基礎上,符號位(首位)不變,其余各個位取反。
(3)補碼
所謂補碼就是在反碼的基礎上按照正常的加法運算加1。
示例如下:
public class Test{ public static void main(String[] args) { System.out.println(toUnsignedString(10)); System.out.println(toUnsignedString(-10)); } final static char[] digits = {'0' , '1'}; /**獲取補碼方法,int類型32位,為了方便查看,所以循環32次 */ private static String toUnsignedString(int value) { StringBuilder sb = new StringBuilder(); sb.append(Integer.toBinaryString(value));//直接使用jdk自帶方法獲取補碼 int length = sb.length(); for (int i = 0; i < 32 - length; i++) { sb.insert(0, 0); } for (int i = 0; i < sb.length(); i++) { if((i + 1) % 5 == 0) sb.insert(i, " "); } return sb.toString(); } }
運行結果
0000 0000 0000 0000 0000 0000 0000 1010
1111 1111 1111 1111 1111 1111 1111 0110
通過上面的案例,可以很清晰的看到正數的補碼 == 原碼,負數的補碼是在其反碼的基礎上加1。
