原码、反码和补码

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值