原码、反码、补码的产生、应用以及优缺点有哪些?
google了一下,看到了這樣一篇文章,注意到文中關于補碼來歷的描述,可以總結如下:
補充解釋一下“模”的概念(不準確):
考慮時鐘上時間的計算,假設現在時針指向數字3,若問“6小時前時針指向的數字是幾”,則可以:
1. 將時針逆時針撥動6格。
2. 將時針順時針撥動12 - 6 = 6格。
兩者的結果是一樣的。這里稱12為“模”。
故有 3時 - 6個小時 = 3時 + (12 - 6個小時),這里可以看到將減法轉換成加法的過程,即“加上模減去絕對值的差”。
所以,假設模是10,有效位數為1,當我們計算 9 - 7 的時候:
9 - 7 => 9 + (10 - 7) = 12,去掉最高的位后,得到2,這是正確的結果。
作者的意思是說,計算機里面所有數都以補碼形式保存,加減運算都是補碼之間的加法運算。然后作者提出了一個我之前沒聽過
的觀點:
補數 和 補碼的定義式 里面,根本就沒有什么符號位。這最高位的1、0是自然出現的,并不是由人來規定的。
的確,符號位在補碼運算里面是“模”,本身并不帶符號的意義。因為計算機將加法轉換成加上一個“負數”,而負數又以補碼的形式
表現。補碼比源碼多一位,從這多出來的一位可以推斷出原來數字的正負號,所以成為了符號位。也可以這樣認為,留出一位
(不全部占滿)的原因是要用“模”來表示正負數。
也就是說,不是特意留出一個符號位,用1和0來表示正負號。而是補碼運算可以用最高位來表示正負,所以符號位誕生了。
那么為什么-128的補碼是10000000?可以這樣理解。-128是一個負數,所以它的補碼是它的“模”減去它的絕對值,即:
100000000 - 10000000 = 10000000那么為什么負數補碼等于源碼的反碼加一呢?可以這樣推導:
100000000 - 10000000 = (11111111 + 00000001) - 10000000 = 11111111 - 10000000 + 1 = 01111111 + 1 //反碼加一 = 10000000由此我們得知,在計算機里面所有的數字都以補碼形式存儲。127存成01111111,-127存成11111111,算減法就變成算加法了,
盡管你看到的是“-”號。
數字在自然界中抽象出來的時候,一棵樹,兩只豬,是沒有正數和負數的概念的
計算機保存最原始的數字,也是沒有正和負的數字,叫沒符號數字
如果我們在內存分配4位(bit)去存放無符號數字,是下面這樣子的
后來在生活中為了表示“欠別人錢”這個概念,就從無符號數中,劃分出了“正數”和“負數”
正如上帝一揮手,從混沌中劃分了“白天”與“黑夜”
為了表示正與負,人們發明了"原碼",把生活應該有的正負概念,原原本本的表示出來
把左邊第一位騰出位置,存放符號,正用0來表示,負用1來表示
但使用“原碼”儲存的方式,方便了看的人類,卻苦了計算機
我們希望 (+1)和(-1)相加是0,但計算機只能算出0001+1001=1010 (-2)
這不是我們想要的結果 (╯' - ')╯︵ ┻━┻
另外一個問題,這里有一個(+0)和(-0)
?
為了解決“正負相加等于0”的問題,在“原碼”的基礎上,人們發明了“反碼”
“反碼”表示方式是用來處理負數的,符號位置不變,其余位置相反
當“原碼”變成“反碼”時,完美的解決了“正負相加等于0”的問題
過去的(+1)和(-1)相加,變成了0001+1110=1111,剛好反碼表示方式中,1111象征-0
人們總是進益求精,歷史遺留下來的問題—— 有兩個零存在,+0 和 -0
?
我們希望只有一個0,所以發明了"補碼",同樣是針對"負數"做處理的
"補碼"的意思是,從原來"反碼"的基礎上,補充一個新的代碼,(+1)
我們的目標是,沒有蛀牙(-0)
有得必有失,在補一位1的時候,要丟掉最高位有得必有失,在補一位1的時候,要丟掉最高位
我們要處理"反碼"中的"-0",當1111再補上一個1之后,變成了10000,丟掉最高位就是0000,剛好和左邊正數的0,完美融合掉了
這樣就解決了+0和-0同時存在的問題
另外"正負數相加等于0"的問題,同樣得到滿足
舉例,3和(-3)相加,0011 + 1101 =10000,丟掉最高位,就是0000(0)
同樣有失必有得,我們失去了(-0) , 收獲了(-8)
以上就是"補碼"的存在方式
?
結論:保存正負數,不斷改進方案后,選擇了最好的"補碼"方案
總結
以上是生活随笔為你收集整理的原码、反码、补码的产生、应用以及优缺点有哪些?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每个开发阶段对应的最流行的Java工具
- 下一篇: Java常见的几种排序算法-插入、选择、