补码原码反码溢出问题

数据的机器层次表示

2.1 补码+原码+反码

1. 原码表示法

符号位单拎出来,正数为0,负数为1。

假设机器字长5位:

1)整数:

+1101, [ x ] 原 [x]_原 [x]=0,1101
-1101, [ x ] 原 [x]_原 [x]=1,1101

2)小数

+0.001, [ x ] 原 [x]_原 [x] =0.0010
-0.001, [ x ] 原 [x]_原 [x] =1.0010

3)真值0表示

[+0] 原 _原 =0,0000

[-0] 原 _原 1,0000

2. 补码表示法

1)方法一

在这里插入图片描述

  • 小数:X=0.0110, [ x ] 补 [x]_补 [x] =0.0110

    ​ X=-0.0110, [ x ] 补 [x]_补 [x] =1.1010(数值部分:.0110 → \rightarrow .1001 → \rightarrow .1010)

  • 整数:X=1101, [ x ] 补 [x]_补 [x] =0,1101

    ​ X=-1101, [ x ] 补 [x]_补 [x] =1,0011(数值部分:1101 → \rightarrow 0010 → \rightarrow 0011)

2)方法二(较简单)

在这里插入图片描述

当X为负数时:从低位至高位,尾数的第一个1及右部的0保持不变,左部的各位取反,符号位保持不变

X=-0.1110011000

[X] 原 _原 = 1.1110011000

[X] 补 _补 = 1.0001101000

​ 3)真值0表示

[+0] 补 _补 =[-0] 补 _补 =0,0000

在这里插入图片描述

在这里插入图片描述

表示范围变化:由于补码±0相同,所以补码多一个负数值为最小负数

3. 反码表示法

1)定义:正数,数值部分与真值形式相同;对于负数,将真值的数值部分按位取反。

  • 小数:X=0.0110,[X] 反 _反 =0.0110

    ​ X=1.0110,[X] 反 _反 =1.1001

  • 整数:X=1101,[X] 反 _反 =0,1101

    ​ X=-1101,[X] 反 _反 =1,0010

​ 2)真值0表示

[+0] 反 _反 =0,0000

[-0] 反 _反 =1,1111

4. 三种表示法比较

1)对于整数,都等于真值本身。

2)最高位都表示符号位。

3)对于真值0,补码只有唯一一种表示形式

4)补码多表示的负数:①整数: − 2 n -2^n 2n ②小数: − 1 -1 1

在这里插入图片描述

2.2 原码补码加减法运算

1. 补码加法

计算 X + Y X+Y X+Y :

X + Y ← [ X + Y ] 补 ← [ X ] 补 + [ Y ] 补 X+Y \leftarrow [X+Y]_补\leftarrow [X]_{补}+[Y]_{补} X+Y[X+Y][X]+[Y]

注意:如果 Y < 0 Y<0 Y<0,那么这里的 [ Y ] 补 [Y]_{补} [Y] 就是负数的补码,但是跟变补没关系(对X同理)

A=0.1011, B=-0.1110,求A+B

[ A ] 补 [A]_{补} [A] =0.1011, [ B ] 原 [B]_{原} [B]= 1.1110, [ B ] 补 [B]_{补} [B]= 1.0010

[ A ] 补 [A]_{补} [A]+ [ B ] 补 [B]_{补} [B]= [ A + B ] 补 [A+B]_{补} [A+B]= 1.1101

[ A + B ] 原 [A+B]_{原} [A+B]= 1.0011

A + B A+B A+B= -0.0010

2. 补码减法

计算 X − Y X-Y XY :

X + Y ← [ X − Y ] 补 ← [ X ] 补 + [ − Y ] 补 X+Y \leftarrow [X-Y]_补\leftarrow [X]_{补}+[-Y]_{补} X+Y[XY][X]+[Y]

根据 [ Y ] 补 [Y]_{补} [Y] [ − Y ] 补 [-Y]_{补} [Y] :

①求 [ Y ] 补 [Y]_{补} [Y]

[ − Y ] 补 [-Y]_{补} [Y]= [ [ Y ] 补 ] 变 补 [[Y]_{补}]_{变补} [[Y]]:将 [ Y ] 补 [Y]_{补} [Y] 连同符号位一起求反,末尾加1

例如:

[ Y ] 原 [Y]_{原} [Y] = 1.0110

[ Y ] 补 [Y]_{补} [Y] = 1.1010

[ − Y ] 补 [-Y]_{补} [Y] =1.1010 → \rightarrow 0.0101 → \rightarrow 0.0110

例题:

A=0.1011, B=-0.0010,求A-B

[ A ] 补 [A]_{补} [A] =0.1011, [ B ] 原 [B]_{原} [B]= 1.0010, [ B ] 补 [B]_{补} [B]= 1.1110, [ − B ] 补 [-B]_{补} [B]= 0.0010

[ A ] 补 [A]_{补} [A]+ [ − B ] 补 [-B]_{补} [B]= [ A − B ] 补 [A-B]_{补} [AB]= 0.1101

[ A − B ] 原 [A-B]_{原} [AB]= 0.1101

A − B A-B AB= 0.1101

3. 符号扩展

场景:某程序需要将8位数与另外一个16位数相加,需要将8位数转化成16位数

例如:00001101/10001101扩展成16位(8位中,包括1位符号位)

1)原码符号扩展

  • 正数:0000000000001101
  • 负数:0000000010001101

2)补码符号扩展

  • 正数:0000000000001101
  • 负数:1111111111110011

2.3 溢出判断

假设被操作数为: [ X ] 补 = X s , X 1 X 2 X 3 . . . X n [X]_补=X_s,X_1X_2X_3...X_n [X]=Xs,X1X2X3...Xn

操作数为: [ Y ] 补 = Y s , Y 1 Y 2 Y 3 . . . Y n [Y]_补=Y_s,Y_1Y_2Y_3...Y_n [Y]=Ys,Y1Y2Y3...Yn

其和(差): [ S ] 补 = S s , S 2 S 1 S 3 . . . S n [S]_补=S_s,S_2S_1S_3...S_n [S]=Ss,S2S1S3...Sn

1. 采用一个符号位

1)正溢: X s = Y s = 0 , S s = 1 X_s=Y_s=0,S_s=1 Xs=Ys=0,Ss=1(两个正数加起来变成了负数)

X = 1011 B = 11 D , Y = 111 B = 7 D X=1011B=11D, Y=111B=7D X=1011B=11D,Y=111B=7D

[ X ] 补 = 0 , 1011 , [ Y ] 补 = 0 , 0111 [X]_补=\textcolor{red}0,1011,[Y]_补=\textcolor{red}0,0111 [X]=0,1011,[Y]=0,0111

[ X + Y ] 补 = 1 , 0010 [X+Y]_补=\textcolor{red}1,0010 [X+Y]=1,0010

X + Y = − 14 D X+Y=-14D X+Y=14D

2)负溢: X s = Y s = 1 , S s = 0 X_s=Y_s=1,S_s=0 Xs=Ys=1,Ss=0 (两个负数加起来变成了正数)

X = − 1011 B = − 11 D , Y = − 111 B = − 7 D X=-1011B=-11D, Y=-111B=-7D X=1011B=11D,Y=111B=7D

[ X ] 补 = 1 , 0101 , [ Y ] 补 = 1 , 1001 [X]_补=\textcolor{red}1,0101,[Y]_补=\textcolor{red}1,1001 [X]=1,0101,[Y]=1,1001

[ X + Y ] 补 = 0 , 1110 [X+Y]_补=\textcolor{red}0,1110 [X+Y]=0,1110

X + Y = 14 D X+Y=14D X+Y=14D

2. 采用进位位

C s , C 1 C 2 . . C n C_s,C_1C_2..C_n Cs,C1C2..Cn

C s C_s Cs :符号位产生的进位

C 1 C_1 C1最高数值位产生的进位

产生溢出的条件: C s ⨁ C 1 C_s\bigoplus C_1 CsC1 (最高数值位产生的进位和符号位产生的进位不同)

1)正溢: C 1 = 1 , C s = 0 C_1=1,C_s=0 C1=1,Cs=0

2)负溢: C 1 = 0 , C s = 1 C_1=0,C_s=1 C1=0,Cs=1

3. 采用变形补码(双符号位)

1)思想:将符号位扩充为两位, S s 1 ( 真 符 : 代 表 该 数 真 正 的 符 号 ) , S s 2 S_{s1}(真符:代表该数真正的符号),S_{s2} Ss1(),Ss2

2)产生溢出的条件: S s 1 ⨁ S s 2 S_{s1}\bigoplus S_{s2} Ss1Ss2

​ ① S s 1 S s 2 = 00 S_{s1}S_{s2}=00 Ss1Ss2=00 ,结果为正数,无溢出

​ ② S s 1 S s 2 = 01 S_{s1}S_{s2}=01 Ss1Ss2=01 ,结果正溢

​ ③ S s 1 S s 2 = 10 S_{s1}S_{s2}=10 Ss1Ss2=10 ,结果负溢

​ ④ S s 1 S s 2 = 11 S_{s1}S_{s2}=11 Ss1Ss2=11 ,结果为负数,无溢出

00,1011+00,0111=01,0010(正溢)

11,1011+11,0111=10,1110(负溢)

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值