1. 原碼反碼補碼概念以及轉換
1.1 原碼 原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值,例如: 原碼:[+1]0000 0001 原碼:[-1]1000 0001 |
1.2 反碼 正數的反碼是其本身 負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反. 原碼:[+1]0000 0001 反碼:0000 0001 原碼:[-1]1000 0001 反碼:1111 1110 |
1.3 補碼 正數的補碼就是其本身 負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1) 原碼:[+1]0000 0001 反碼:0000 0001 補碼:0000 0001 原碼:[-1]1000 0001 反碼:1111 1110 補碼:1111 1111 |
#include <stdio.h>
int main(int argc, const char * argv[]) { // 其實數據存儲在內存中都是存儲的二進制 // 二進制又可以分爲原碼、反碼、補碼 // 其實最終存儲在內存中的是補碼 // int佔4個字節 1個字節8位所以整形就站 32 位 int num = 12; /* // 12的二進制 12在內存中存儲的是它的補碼 00000000 00000000 00000000 00001100 正數:(三碼相同)正數的原碼就是它反碼,也是它的補碼
-12 二進制的最高位我們稱之爲符號位 如果符號位是0代表是一個正數, 如果符號位是1代表是一個負數
10000000 00000000 00000000 00001100 (-12的原碼) 11111111 11111111 11111111 11110011(反碼, 符號位不變其它位取反)
11111111 11111111 11111111 11110011 +00000000 00000000 00000000 00000001 _____________________________________________ 11111111 11111111 11111111 11110100(補碼 , 反碼+1)
結論:無論正數負數在內存中存儲的都是補碼
11111111 11111111 11111111 11110101 (補碼) -00000000 00000000 00000000 00000001 (-1) _____________________________________________ 11111111 11111111 11111111 11110100 (反碼) 10000000 00000000 00000000 00001011
*/ printf("%d\n", 0b11111111111111111111111111110101); return 0; } |
2. 爲什麼要引入反碼、補碼?
主要是爲了方便計算機計算,因爲計算機制作加法計算,沒有減法計算 1、由於最高爲是符號位,如果是0就代表正數,如果是1就代表是負數 2、如果直接存儲原碼,計算機在計算的時候還需要判斷最高位才能計算,效率較低 3、爲了方便計算機計算,所以有了反碼和補碼,有了反碼和補碼之後,以後計算機就不需要判斷最高位,直接計算即可(計算機只做加法計算) 1 + 1 0001 + 0001 ———————— 0010 ==2 1 - 1 == 1 + (-1)==計算機只會做加法 0000 0001 原碼 + 1000 0001 原碼 ———————————————— 1000 0010 == -2
1 - 1 == 1 + (-1)== 計算機只會做加法 0000 0001 原碼(+1反碼) + 1111 1110 反碼 ———————————————— 1111 1111 == 反碼 將計算出來的反碼轉爲原碼,再見原碼轉換爲十進制 1000 0000 == 原碼 == -0
1 - 1 == 1 + (-1)== 計算機只會做加法 0000 0001 (+1補碼) + 1111 1110 (-1補碼) —————————————————— 1 0000 0000 == 0 補碼 |
最後補充一點 這樣0用[0000 0000]表示, 而以前出現問題的-0則不存在了.而且可以用[1000 0000]表示-128: (-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]補 + [1000 0001]補 = [1000 0000]補 -1-127的結果應該是-128, 在用補碼運算的結果中, [1000 0000]補碼就是-128. 但是注意因爲實際上是使用以前的-0的補碼來表示-128, 所以-128並沒有原碼和反碼錶示.(對-128的補碼錶示[1000 0000]補算出來的原碼是[0000 0000]原, 這是不正確的) 有人會問 10000000這個補碼錶示的哪個數的補碼呢? 其實這是一個規定,這個數表示的是-128所以n位補碼能表示的範圍是 -2^(n-1)到2^(n-1)-1 比n位原碼能表示的數多一個 |