1. 程式人生 > >原碼、反碼、補碼

原碼、反碼、補碼

方法 n-1 字長 執行 溢出 註意 就會 減負 原因

數在計算機中是以二進制形式表示的。 
數分為有符號數和無符號數。 
原碼、反碼、補碼都是有符號定點數的表示方法。 
一個有符號定點數的最高位為符號位,0是正,1是副。 
 
以下都以8位整數為例, 
 
原碼就是這個數本身的二進制形式。 
例如
0000001 就是+1
1000001 就是-1 
 
正數的反碼和補碼都是和原碼相同。 
 
負數的反碼是將其原碼除符號位之外的各位求反 
[-3]反=[10000011]反=11111100 
負數的補碼是將其原碼除符號位之外的各位求反之後在末位再加1。 
[-3]補=[10000011]補=11111101 
一個數和它的補碼是可逆的。 
 
為什麽要設立補碼呢? 
 
第一是為了能讓計算機執行減法: 
[a-b]=a+-b)補
 
第二個原因是為了統一正0和負0 
正零:00000000 
負零:10000000 
這兩個數其實都是0,但他們的原碼卻有不同的表示。 
但是他們的補碼是一樣的,都是00000000 
特別註意,如果+1之後有進位的,要一直往前進位,包括符號位!(這和反碼是不同的!) 
[10000000]補 
=[10000000]反+1 
=11111111+1 
=(1)00000000 
=00000000(最高位溢出了,符號位變成了0) 
 
有人會問 
10000000這個補碼表示的哪個數的補碼呢? 
其實這是一個規定,這個數表示的是-128 
所以n位補碼能表示的範圍是 
-2^(n-1)到2^(n-1)-1 
比n位原碼能表示的數多一個
 
又例:
1011 
原碼:01011 
反碼:01011 //正數時,反碼=原碼 
補碼:01011 //正數時,補碼=原碼 
 
-1011 
原碼:11011 
反碼:10100 //負數時,反碼為原碼取反 
補碼:10101 //負數時,補碼為原碼取反+1 
 
0.1101 
原碼:0.1101 
反碼:0.1101 //正數時,反碼=原碼 
補碼:0.1101 //正數時,補碼=原碼 
 
-0.1101 
原碼:1.1101 
反碼:1.0010 //負數時,反碼為原碼取反 
補碼:1.0011 //負數時,補碼為原碼取反+1 
 
在計算機內,定點數有3種表示法:原碼、反碼和補碼
 
所謂原碼就是前面所介紹的二進制定點表示法,即最高位為符號位,“0”表示正,“1”表示負,其余位表示數值的大小。
 
反碼表示法規定:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
 

補碼表示法規定:正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1。

兩正數相加怎麽變成了負數???

1)(+72)+(+98)=?

0 1 0 0 1 0 0 0 B +72

0 1 1 0 0 0 1 0 B +98

1 0 1 0 1 0 1 0 B -86

兩負數相加怎麽會得出正數???

2)(-83)+(-80)=?

1 0 1 0 1 1 0 1 B -83

1 0 1 1 0 0 0 0 B -80

0 1 0 1 1 1 0 1 B +93

思考:這兩個題目,按照正常的法則來運算,但結果顯然不正確,這是怎麽回事呢?

答案:這是因為發生了溢出。

如果計算機的字長為n位,n位二進制數的最高位為符號位,其余n-1位為數值位,采用補碼表示法時,可表示的數X的範圍是 -2的n-1次冪≤X≤2的n-1次冪-1

當n=8時,可表示的有符號數的範圍為-128~+127。兩個有符號數進行加法運算時,如果運算結果超出可表示的有符號數的範圍時,就會發生溢出,使計算結果出錯。很顯然,溢出只能出現在兩個同符號數相加或兩個異符號數相減的情況下。

對於加法運算,如果次高位(數值部分最高位)形成進位加入最高位,而最高位(符號位)相加(包括次高位的進位)卻沒有進位輸出時,或者反過來,次高位沒有進位加入最高位,但最高位卻有進位輸出時,都將發生溢出。因為這兩種情況是:兩個正數相加,結果超出了範圍,形式上變成了負數;兩負數相加,結果超出了範圍,形式上變成了正數。

而對於減法運算,當次高位不需從最高位借位,但最高位卻需借位(正數減負數,差超出範圍),或者反過來,次高位需從最高位借位,但最高位不需借位(負數減正數,差超出範圍),也會出現溢出。

在計算機中,數據是以補碼的形式存儲的,所以補碼在c語言的教學中有比較重要的地位,而講解補碼必須涉及到原碼、反碼。

在n位的機器數中,最高位為符號位,該位為零表示為正,為一表示為負;其余n-1位為數值位,各位的值可為零或一。當真值為正時,原碼、反碼、補碼數值位完全相同;當真值為負時,原碼的數值位保持原樣,反碼的數值位是原碼數值位的各位取反,補碼則是反碼的最低位加一。註意符號位不變。

原碼、反碼、補碼