數在計算機中是以二進制形式表示的。
數分為有符號數和無符號數。
原碼、反碼、補碼都是有符號定點數的表示方法。
一個有符號定點數的最高位為符號位,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。
附錄:把十進制數轉換為機器碼的C++程序代碼
#include <iostream>
using namespace std;
const int MAX = 32;
void Binary(char b[], int x); //將x轉換為二進制數
void TrueForm(char b[], int x); //獲取原碼
void RadixMinus(char b[], int x); //獲取反碼
void Complement(char b[], int x); //獲取補碼
void TruthValue(char b[], int x);//獲取真值
int main()
{
int x = 1;
char b[MAX+1]={0};
cout << "十進制數:" << x << endl;
TruthValue(b, x);//獲取真值
cout << "真值:" << b << endl;
TrueForm(b, x); //獲取原碼
cout << "原碼:" << b << endl;
RadixMinus(b, x);//獲取反碼
cout << "反碼:" << b << endl;
Complement(b, x);//獲取補碼
cout << "補碼:" << b << endl;
cout << "十進制數:" << -x << endl;
TruthValue(b, -x);//獲取真值
cout << "真值:" << b << endl;
TrueForm(b, -x); //獲取原碼
cout << "原碼:" << b << endl;
RadixMinus(b, -x);//獲取反碼
cout << "反碼:" << b << endl;
Complement(b, -x);//獲取補碼
cout << "補碼:" << b << endl;
system("pause");
return 0;
}
void Binary(char b[], int x)//將x轉換為二進制數
{
for (int i=MAX-1; i>=0; i--)
{
b[i] = (x & 1) + '0';
x >>= 1;
}
b[MAX] = '\0';
}
void TrueForm(char b[], int x) //獲取原碼:根據數學表達式求得
{
if (x >= 0)
Binary(b, x);
else
Binary(b, (1<<(MAX-1)) - x);
}
void RadixMinus(char b[], int x) //獲取反碼:正數的反碼=補碼;負數的反碼=補碼-1
{
if (x >= 0)
Binary(b, x);
else
Binary(b, x - 1);
}
void Complement(char b[], int x) //獲取補:數據在計算機中以補碼形式存儲,直接轉換即可
{
Binary(b, x);
}
void TruthValue(char b[], int x)//獲取真值:根據原碼獲得真值
{
TrueForm(b, x);
b[0] = (b[0] == '0') ? '+' : '-';
}
參考文獻:
(1)Boater的博客:《反碼和補碼技術是怎樣被提出的?》
http://blog.tianya.cn/blogger/post_show.asp?BlogID=227218&PostID=7046448
(2)發帖:《閑扯原碼,補碼和反碼》
http://www.shnenglu.com/goal00001111/
posted on 2010-09-23 19:04
王秋林 閱讀(426)
評論(0) 編輯 收藏 引用