JavaSE教程-03深入探究原码,反码,补码-扩展
1.原碼,反碼,補碼的基礎概念和計算方法
在搞清楚為什么計算機要使用補碼之前,我們先搞清楚一個基本知識點,就是原碼,反碼,補碼的計算方式。
對于一個數,計算機要使用一定的編碼方式進行存儲,原碼,反碼,補碼是機器存儲一個具體數字的編碼方式。
原碼
原碼就是符號位加上真值的絕對值,即用第一位表示符號,其他為表示值。
比如8位二進制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符號位,所以8位二進制數的取值范圍是:
[1111 1111,0111,1111]
即
[-127,127]
原碼是我們最容易理解的計算方式。
反碼
正數的反碼是其本身
負數的反碼是在其原碼的基礎上,符號位不變,其余逐個取反
[+1]=[0000 0001]原=[0000 0001]反
[-1]=[1000 0001]原=[1111 1110]反
當反碼表示一個負數的時候,人腦是無所直觀得知他的數值,所以需要將其轉化為原碼再計算。
補碼
正數的補碼就是其本身
負數的補碼是在其反碼的基礎上加1
[+1]=[0000 0001]原=[0000 0001]反=[0000 0001]補
[-1]=[1000 0001]原=[1111 1110]反=[1111 1111]補
同樣,對于負數的補碼,人腦是無所直觀得知他的數值,所以需要將其轉化為原碼再計算。
2.為何要使用原碼,反碼,補碼
首先要求大家要先掌握這三種編碼的計算方式。
下面我們來關注負數的情況
[-1]=[1000 0001]原=[1111 1110]反=[1111 1111]補
既然原碼才是我們直觀最能識別的方式,為什么還要有反碼和補碼?
首先,因為人腦可以知道第一位是符號位,在計算的時候,我們會根據符號位,選擇對數值的加減。但對于計算機,要讓計算機辨別“符號位”顯然會讓計算機的基礎電路設計變得非常復雜,所以人們想出了將符號位也參與運算的方法。
我們知道,減去一個正數等于加上一個負數,即1-1=1+(-1)=0,所以
計算機只有加法沒有減法
,這樣計算機的運算設計就更簡單了。
所以,當我們計算1-1=0時,如果用原碼的方式來計算結果如下:
1-1=1+(-1)=[0000 0001]原+[1000 0001]原=[1000 0010]原=-2
結論:如果用原碼表示,讓符號位也參與計算,顯然結果是不對的,這就是為什么計算機內部不使用原碼表示一個數。
為了解決原碼做減法,反碼出現了
1-1=1+(-1)=[0000 0001]原+[1000 0001]原=[0000 0001]反+[1111 1110]反=[1111 1111]反=[1000 0000]原=-0
發現使用反碼計算減法,結果的數值是正確的。而現在的問題就出現在“0”這個特殊的數值上。雖然人是可以理解+0和-0是一樣的,但是0帶符號是沒有任何意義的。
所以會出現[0000 0000]原和[1000 0000]原,兩個編碼都表示0
為了解決“0”的問題,補碼出現了
1-1=1+(-1)=[0000 0001]原+[1000 0001]原=[0000 0001]反+[1111 1110]反=[0000 0001]補+[1111 1111]補=[0000 0000]補=[0000 0000]原
這樣0就用[0000 0000]表示,而之前的-0則不存在。
那么[1000 0000]表示哪個數值,即-128
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1110]反+[1000 0000]反=[1111 1111]補 + [1000 0001]補 = [1000 0000]補
所以在補碼運算中 [1000 0000]補表示-128.
注意,實際上是使用以前的-0的補碼來表示-128, 所以-128并沒有原碼和反碼表示.(對-128的補碼表示[1000 0000]補算出來的原碼是[0000 0000]原, 這是不正確的)
使用補碼, 不僅僅修復了0存在兩個編碼的問題, 而且還能夠多表示一個最低數. 這就是為什么8位二進制, 使用原碼或反碼表示的范圍為[-127, +127], 而使用補碼表示的范圍為[-128, 127].
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的JavaSE教程-03深入探究原码,反码,补码-扩展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JavaSE04】Java中循环语句f
- 下一篇: 【JavaSE05】Java中方法与重载