您的位置:首页 > 其它

原码、反码和补码

2011-09-03 21:26 183 查看
1、原码、反码和补码的表示方法

(1)原码:在数值前直接加一符号位的表示法。

[+7]原= 0 0000111 B

[-7]原= 1 0000111 B

注意:a. 数0的原码有两种形式:

[+0]原=00000000B [-0]原=10000000B

8位二进制原码的表示范围:-127~+127

(2)反码:

正数:正数的反码与原码相同。

负数:负数的反码,符号位为“1”,数值部分按位取反。

例如: 符号位 数值位

[+7]反= 0 0000111 B

[-7]反= 1 1111000 B

注意:a. 数0的反码也有两种形式,即

[+0]反=00000000B

[- 0]反=11111111B

8位二进制反码的表示范围:-127~+127

(3)补码:

在计算机系统中,数值一律用补码来表示(存储)。

主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补

码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。

数值的补码表示也分两种情况:

正数:正数的补码和原码相同。

负数:负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。

[+7]补= 0 0000111 B

[-7]补= 1 1111001 B

2、已知一个数的补码,求原码的操作分两种情况:

(1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。

(2)如果补码的符号位为“1”,表示是一个负数。按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1 。

例:已知某数X的补码11101110B,试求其原码。

解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。

1 1 1 0 1 1 1 0 补码

1 0 0 1 0 0 0 1 符号位不变,数值位取反

1 +1

1 0 0 1 0 0 1 0 原码

若字长为8位,则补码所表示的范围为-128~+127。这是一个规定,10000000这个补码表示的这个数是-128。所以n位补码能表示的范围是-2^(n-1)到2^(n-1)-1,比n位原码能表示的数多一个。

byte类型的范围:(负数最小值,1既是符号位又是值位)

Dec: -128 -1 0 127

Bin: 1000 0000 1111 1111 0000 0000 0111 1111

32位Int类型范围:

Dec: -2147483648 -1 0 2147483647

Hex: 0x80000000 0xFFFFFFFF 0x00000000 0x7FFFFFFF

3、溢出

两个有符号数进行加法运算时,如果运算结果超出可表示的有符号数的范围时,就会发生溢出,使计算结果出错。很显然,溢出只能出现在两个同符号数相加或两个异符号数相减的情况下。

对于加法运算,如果次高位(数值部分最高位)形成进位加入最高位,而最高位(符号位)相加(包括次高位的进位)却没有进位输出时,或者反过来,次高位没有进位加入最高位,但最高位却有进位输出时,都将发生溢出。因为这两种情况是:两个正数相加,结果超出了范围,形式上变成了负数;两负数相加,结果超出了范围,形式上变成了正数。

而对于减法运算,当次高位不需从最高位借位,但最高位却需借位(正数减负数,差超出范围),或者反过来,次高位需从最高位借位,但最高位不需借位(负数减正数,差超出范围),也会出现溢出。

#include <iostream>
#include <cstring>
using namespace std;

int main(){
int a = 0x7fffffff;
int b = 1;

printf("%x\n", a);
printf("%d\n", a);

printf("%x\n", a + 1);
printf("%d\n", a + 1);

system("PAUSE");
return 0;
}


结果:

7fffffff

2147483647

80000000

-2147483648
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: