1. 程式人生 > >原碼,反碼,補碼的簡單理解

原碼,反碼,補碼的簡單理解

今天開始看阿里的<<碼出高效:Java開發手冊>>,頭一章便是計算機基礎。計算機的基礎世界一切都是由0和1組成。

既然是0和1的世界,肯定就逃不了原碼,反碼跟補碼的使用。
首先我們直到一個byte代表一個位元組,有8位。

如果用byte即8位儲存一個數字的話那範圍是多少?

答案是:-128~127.

擴充套件一下:

Integer i1 = 100;
Integer i2 = 100;

Integer i3 = 200;
Integer i4 = 200;
System.err.println(i1 == i2);
System.err.println(i3 == i4);

第一個會列印true,第二個會列印false。
這是什麼原因呢,原來在JDK1.5中對整形資料採用了快取,快取-128 ~ 127範圍的資料。

回到正題:

為啥會有原碼,反碼,補碼的概念呢?
因為加減法是高頻運算,使用同一個運算器,,可以減少中間變數儲存的開銷也降低了CPU內部的設計複雜度,所以我們將減法轉換成加法運算,比如1-2轉換為1+(-2).

而原碼,反碼,補碼的存在就是為了解決其中的問題。
關於原碼,反碼,補碼的介紹與應用,網上已經有了很多優秀的詳解,我這裡就不多累贅了,直接貼網址了,就這麼直接(好吧,我懶)
https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

總結:

  1. 要區分正數和負數:最左邊的是符號位,0代表正數,1代表負數
  2. 正數的反碼和補碼都與原碼相同。
  3. 負數的反碼為對該數的原碼除符號位外各位取反。
  4. 負數的補碼為對該數的原碼除符號位外各位取反,然後在最後一位加1

注意:如果沒有補碼,只有反碼的話,0的表示有兩個:0000 0000和-0000 0000
所以出現了補碼:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]補 + [1000 0001]補 = [1000 0000]補

所以對應一開始的問題如果用8位儲存01的話 範圍是-128~127,
其中0000 0000代表0,-0000 0000代表-128

題外話:
小心結果溢位,如果計算結果需要9位儲存,而我們只有8位,這個時候就出現結果溢位的問題,即在資料運算的過程中,超出規定的表示範圍。一旦溢位,計算結果就是錯誤的,所以在各個程式語言中規定了不同數字型別的表示範圍,有相應的最大值和最小值。