补码反码原码

  • 原码、补码、反码相互转换

原码是机器数中最简单的一种表示形式,符号位数为 0 0 0 表示正数,符号位 1 1 1 表示负数, 0 0 0 表示正数,符号位是在计算机中用一个数的最高位来存放符号,而真值是带有 + + + 或者是 − - 符号的数,由于计算机分不清正负符号,所以需要转换成原码
下面这是一个八比特寄存器

2 7 2^7 27 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20

最高位 2 7 2^7 27表示符号位正与负

  • 例如:十进制正数 14 14 14转换成二级制为 1110 1110 1110,由于是在八位寄存器中所以应该为
2 7 2^7 27 2 6 2^6 26 2 5 2^5 25 2 4 2^4 24 2 3 2^3 23 2 2 2^2 22 2 1 2^1 21 2 0 2^0 20
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0

最高位表示符号
用逗号将符号位和数值位分隔开,当 x = − 1100 x=-1100 x=1100时, [ x ] 原 = 2 4 − ( − 1110 ) = 1 , 1110 [x]_{原} =2^4-(-1110)=1,1110 [x]=24(1110)=1,1110

上面的是整数,下面是小数原码:
[ x ] 原 = { x 1 > x ≥ 0 1 − x 0 ≥ x > − 1 [x]_{原}= \begin{cases} x& \text{} 1>x\ge0 \\ 1-x& \text{} 0\ge x>-1\end{cases} [x]={x1x1>x00x>1
x x x为真值

  • 例如
    x = 0.1101 x=0.1101 x=0.1101时, [ x ] 原 = 0.1101 [x]_{原}=0.1101 [x]=0.1101, x = − 0.1101 x=-0.1101 x=0.1101时, [ x ] 原 = 1 − ( − 0.1101 ) = 1.1101 [x]_{原}=1-(-0.1101)=1.1101 [x]=1(0.1101)=1.1101

当然既然能能根据真值求原码,反过来原码也可以求真值

  • 例如
    [ x ] 原 = 1.0011 [x]_{原}=1.0011 [x]=1.0011时, x = 1 − [ x ] 原 = 1 − 1.0011 = − 0.0011 x=1-[x]_{原}=1-1.0011=-0.0011 x=1[x]=11.0011=0.0011

注意:当 x = 0 x=0 x=0时,有两种形式来表示
[ + 0.0000 ] 原 = 0.0000 [+0.0000]_{原}=0.0000 [+0.0000]=0.0000 [ − 0.0000 ] 原 = 1 − ( 0.0000 ) = 1.0000 [-0.0000]_{原}=1-(0.0000)=1.0000 [0.0000]=1(0.0000)=1.0000
所以 [ + 0 ] 原 [+0]_{原} [+0]不等于 [ − 0 ] 原 [-0]_{原} [0]

正数:
原码 → 不变 反码 → 不变 补码 原码\xrightarrow[]{不变}反码\xrightarrow[]{不变}补码 原码不变 反码不变 补码
并且这个从补码到原码也是一样都是不变的

负数:
原码 → 数值取反 符号位不变 反码 → 末尾 + 1 补码 原码\xrightarrow[数值取反]{符号位不变}反码\xrightarrow[]{末尾+1}补码 原码符号位不变 数值取反反码末尾+1 补码
补码转反码执行相反的运算——末尾 − 1 -1 1
这里的数值取反意思是 0 0 0变成 1 1 1 1 1 1变成 0 0 0(除了符号位不变)

  • 例如:
    + 17 +17 +17 (八比特位)原码、反码、补码都为 0 , 0010001 0,0010001 0,0010001
    − 17 -17 17 (八比特位)原码为 1 , 0010001 1,0010001 1,0010001,反码为 1 , 1101110 1,1101110 1,1101110,补码 1 , 1101111 1,1101111 1,1101111

在这里补充一下无符号位减法运算
01100011 − 00001001 = 01100011-00001001= 0110001100001001= 我们手算的时候可以进行数不够可以进行借位
但是在计算机中实现减法中成本较高,所以可以将计算方法变化一下,将其变成加法计算器能完成的
首先,将被减数不变,减数全按位取反,再末位 + 1 +1 +1,减法变加法,将 00001001 00001001 00001001转成 11110111 11110111 11110111,最后与被减数相加得 01100011 + 11110111 = 101011010 01100011+11110111=101011010 01100011+11110111=101011010 但是我在这里限制的是八比特寄存器 多出来了一位 最后为 01011010 01011010 01011010

这里有一个补码与原码之间快速切换的技巧(两者可以相互转换)
原码 → 这个左边所有的数值位取反 从右往左找到第一个 1 补码 原码\xrightarrow[这个左边所有的数值位取反]{从右往左找到第一个1}补码 原码从右往左找到第一个1 这个左边所有的数值位取反补码

  • 例如:
    − 12 -12 12
    原码为 10001100 10001100 10001100 这里我们为了更加容易好看,绘制了一个表格
1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0
↑ \uparrow

从右往左第一个 1 1 1 从这个 1 1 1开始也就是从箭头所示开始将所有的数值进行取反得到

原码 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0
补码 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0

反码与补码也可以进行加减运算,方式与原码计算方法一样

[ A ] 补码 + [ B ] 补码 [A]_{补码}+[B]_{补码} [A]补码+[B]补码 [ A ] 补码 − [ B ] 补码 [A]_{补码}-[B]_{补码} [A]补码[B]补码
[ A ] 反码 + [ B ] 反码 [A]_{反码}+[B]_{反码} [A]反码+[B]反码 [ A ] 反码 − [ B ] 反码 [A]_{反码}-[B]_{反码} [A]反码[B]反码

三种码可以能在一起混合计算,但是没有什么意义

  • 这是我第一次写博客,请多多指教
  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值