一、正數
正數的源碼、反碼、補碼都是相同的。
二、負數
1、負數的源碼與反碼的相互轉換
負數的源碼轉換為反碼:符號位不變,數值位按位取反。
例如:
源碼:1000 1100
反碼:1111 0011
負數的反碼轉換為源碼:符號位不變,數值位按位取反。
例如:
反碼:1011 0101
源碼:1100 1010
2、負數的源碼和補碼的相互轉換
負數的源碼轉換為補碼:1、先轉換為反碼(符號位不變,數值位按位取反)2、在反碼的基礎上末位加一。
例如:
源碼:1010 0101 反碼:1101 1010 補碼:1101 1011
負數的補碼轉換為源碼:符號位不變,數值位按位取反,末位加一。
例如:
補碼:1110 1011 補碼取反:1001 0100 源碼:1001 0101
3、負數的反碼和補碼的相互轉換
負數的反碼轉換為補碼:末位加一
例如:
反碼:1100 1110
補碼:1100 1111
負數的補碼轉換為反碼(源碼的反碼):末位減一
例如:
補碼:1100 1110
反碼:1100 1101 (借位減)
4、正數取反
先將正數源碼按位取反,得到一個負數,由於負數以補碼形式存在,再轉換為負數的反碼,最后末位加一得到補碼。
例如:
0000 1100 #源碼 1111 0011 #正數取反得到負數的源碼 1000 1100 #負數的源碼取反后得到反碼 1000 1101 #反碼加一得到補碼
5、計算機存儲數據以補碼的形式(原文鏈接:https://blog.csdn.net/evinsyx/article/details/79559863)
數據是以一串二進制的數字儲存在計算機中,而數據轉化為二進制的數值就是稱為原碼。比如說整數10的原碼為0000 1010(八位二進制),其中最左邊的一位作為符號位,值為0即為正數,值為1為負數。
但是如果直接以原碼的形式存在計算機中,那么為引來一個bug: -0和+0的原碼形式不統一,-0的原碼為1000 0000,而+0的原碼為+0000 0000。但是在數學上-0和+0的意義應該是一樣的,均為0。
這還不是計算機不以原碼儲存的一個原因,另外一個原因就在於計算機它只能做加法運算,所以計算機的減法運算還要轉化成加法運算來實現。那通過什么辦法實現呢。
平時日常生活所用到的時鍾,我們可以把時鍾的時間值看做是十二進制的一種計數器(比如1點鍾和13點鍾的時針指的是同一個值),所以說 5 - 3 = 2 。 這個式子可以看作是五點鍾逆時針轉了3個鍾到了2點鍾。 我們可以把式子變一下, 5 - 2 = 5 + ( 12 - 2 ) = 15 = 3 (這里15 = 3 是因為 15點的時鍾指的是3點鍾,也可以看成15超過了12,所以舍去了12變成了3)。
所以在這里我們引出一個概念,這里的容量12被稱為模,我個人認為模應該是指在一種數學環境中數可選的容量,就像二進制中的模為2。而上面的推斷也啟示了我們可以將減數變成模減去減數的絕對值,然后和被減數相加得到原本減法的結果。所以我們可以在原碼中,把正數的原碼不變,負數的原碼通過模減去這個原碼得到的一串新的二進制數字串,稱作補碼(根據規定,我們將正數的補碼等於原碼)。比如說-3的原碼為1000 0011,而八位二進制數的模為1 0000 0000,所以其補碼為1 0000 0000 - 1000 0011 = 1111 1101,即1111 1101是-3的補碼。
我們可以吧這個運算過程轉化一下 1 0000 0000 - 1000 0011 = 1111 1111 - 1000 0011 + 0000 0001,把式子轉化成這樣子后,由於1111 1111 - 1000 0011的運算就跟把1000 0011的所有位數的值取反一樣,而取反得到的原碼則被稱為反碼(在規定中,正數的反碼等於原碼,而負數取反過程中其符號位不變,所以可能會與之前講的求補碼的過程有沖突,而作者在之前的例子會出現改變符號位的可能,所以按照規定還是保持符號位不變,其他位取反),所以上式子中,1000 0011的反碼就是為0111 1100。接下來在原先求負數補碼的過程中,我們將式子化成1111 1111 - 1000 0011(在取反) + 0000 0001,那么在這種求負數補碼的過程也可以是將負數原碼取反后再加一,這也是一般求負數補碼的方法。
而有了補碼這種概念后,我們會發現+0的補碼是0000 0000,而-0的原碼為1000 0000,通過取反加一后我們會發現-0的補碼竟然也是0000 0000,正好解決了會出現兩個零的可能,而且其中-128的補碼是1000 0000(可以帶入式子算,其中-128的原碼也為1000 0000,所以可以算出其補碼正好為1000 0000)。所以補碼能夠使每個數一一對應,這也是計算機儲存數據使用補碼而不是用原碼。