补码及原理

机器数与真值

1.机器数:
一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1
栗子:

8位整型数据为例
十进制中的+3在计算机中转换成二进制为 0000 0011
十进制中的-3在计算机中转换成二进制为 1000 0011

2.真值:
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面有
符号数10000011,其最高位1代表负,其真正数值是-3而不是形式值131(10000011转换成十进制等于131).所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
栗子:

有符号位:
二进制 0000 0011 真值为 (+000 00113
二进制 1000 0011 真值为 (-000 0011-3
无符号位:
二进制 1000 0011 真值为  (所见即真)131

参考地址

原码,反码,补码

该注意的:
首先:确定这些码存在的意义——方便计算机计算减法(或者说处理负数)
其次:在正数原码反码补码都相同 (反码和补码是为了解决负数问题出现的,我认为没必要去强调为什么正数对应的这些码都相同,我查了半天资料没一个靠谱的。)
以下都用一Byte(8位)的数据来举例

原码

原码就是加了一位符号位的二进制数,正数符号位为0,负数符号位为1,符号位为最高位。

当前Byte数据八位:
|        |	|	|	|	|	|	|	|
|-符号位-|----------数据位-----------|

先将数的绝对值转换为二进制依照数据位往左用0补齐,最高位为符号位原数据正负在最左边一位换0或换1(此处需注意本身的数据长度)。

十进制绝对值的二进制补齐数据位原码
+311000 00110000 0011
-311000 00111000 0011

特殊的存在

十进制绝对值的二进制补齐数据位原码
+00000 00000000 0000
-00000 00001000 0000

反码

负数反码才有意义(文中讨论反码皆为负数)
简单的,负数反码就是对应正数的原码按位取反(0变1,1边0)。

十进制对应正数的原码反码
-30000 00111111 1100

补码

负数补码才有意义(文中讨论补码皆为负数)
简单的,负数补码就是对应反码再加1(二进制下)。

十进制对应正数的反码补码
-31111 11001111 1101

补码加减

使用原码进行计算的时候,对于人而言能够很轻易的辨别出符号位,然后直接对其他位数值进行计算。然而对于计算机的设计而言辨别出符号位就是一项非常复杂的工程,所以设计的时候就考虑让符号位直接参与计算,这样设计计算机就十分简单了。 对于加法而言符号位对于计算并没有影响,对于减法而言则考虑通过加上负数来转换为加法的方式进行计算。 如果通过原码来直接进行减法计算:

3 - 2 
= 3 + (-2)
= 0000 0011 + 1000 0010()
= 1000 0101
= -5

结果显而易见,如果通过原码来直接让符号位参与运算的话是不正确的,所以为了解决减法的问题引入了补码的概念。

如果通过补码来进行减法计算:

3 - 2
 = 3 + (-2)   
 = 0000 0011 + 1000 0010()
 = 0000 0011 + 1111 1110()
 = 1 0000 0001 去除溢出位
 = 0000 0001
 = 1

4 - 4
 = 4 + (-4)   
 = 0000 0100 + 1000 0100()
 = 0000 0100 + 1111 1100()
 = 1 0000 0000 去除溢出位
 = 0000 0000
 = 0

-1 - 127
 =-1+ (-127)   
 = 1000 0001 + 1111 1111()
 = 1111 1111 + 1000 0001()
 = 1 1000 0000 去除溢出位
 = 1000 0000
 = -128(特殊的去除了原有的-0,变为了-128

所以普遍的有符号8位Btye数据范围:-128~127

读书人都喜欢深入

那为什么补码计算可以非常巧妙的计算出结果呢?
我们主要要解决的问题就是负数的表示,而众所周知,绝对值相等的两个正负数之和为0
假设我们有正数 0000 1111,我们如何表示其相反数呢?一般我们的思路是,找一个数,跟它相加的结果等于0,但是我们发现,要找出一个与它相加后结果等于0的数还是要略加思考一下的(因为要计算进位),所以,为何不找出一个与它相加后结果是11111 1111的数,然后该数+1即是我们所要的答案啦。
于是,很容易的:

    0000 1111 + 1111 0000 + 1 
  = 1111 1111 + 1
  =10000 0000

一目了然,1111 0001 就是我们想要的答案了,那么我们是怎么得到这个相反数的呢?
首先,找出一个数与它加起来结果是全1的,这个数便是它的反码,然后这个数再加1,这便是它的相反数了,也是我们说的补码。
举个栗子:

原数原码反码补码
-31000 00111111 11001111 1101
30000 00110000 00110000 0011

3-3 = (1)0000 0000 = 0
由此,得到了负数的二进制编码由补码组成。
一个小小的例子解释了为何补码需要原码取反之后再加1,是不是很神奇?

在其他地方还看见将(-128~127)与0-255的映射表格如下:

0-255-128~127二进制
255-111111111
254-211111110
253-311111101
252-411111100
251-511111011
246-1011110110
236-2011101100
226-3011100010
216-4011011000
206-5011001110
196-6011000100
186-7010111010
156-10010011100
129-12710000001
128-12810000000
12712701111111
10010001100100
707001000110
606000111100
505000110010
404000101000
303000011110
202000010100
101000001010
5500000101
4400000100
3300000011
2200000010
1100000001
0000000000

没有比人更高的山,没有比脚更远的路。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值