电子学杂记篇3-永不过时的补码

 “补码”(英文表示为:2’s Complement)是数字电子学中一个非常重要的概念,它广泛应用于各种数字系统中(比如计算机、FPGA系统),主要用来表示负数。

博主小飞遇到过很多FPGA初学者,甚至是一些FPGA老手,遇到FPGA处理负数时,就焦头烂额、无从下手,原因无外乎两个:

一是不了解verilog处理负数的语法(博主小飞在verilog专栏中已详细介绍);

二是曾经的数电没学好,特别对“补码”这块知识要点可能一知半解。

本篇博主小飞主要介绍数字电子学中补码的相关要点,如果大家对补码很了解,或者说处理负数时得心应手,就不用在这里浪费宝贵的时间了~

要点1:为什么会有补码?

补码允许表达负数,也可以理解为创造补码就是为了方便减法运算的。

要点2:给定一个二进制数(原码),那么它的补码怎么得到?

根据规则,二进制原码的补码为原码所有位取反,然后在最低位加1,简称取反加1。例如4bit位宽的二进制数(原码)1001的补码为0110+1=0111;8bit位宽的二进制数(原码)00100110的补码为11011001+1=11011010。

要点3:如果已经知道了一个二进制数(原码)的补码,那么该二进制数(原码)怎么得到?

同样的和要点2一样,将该补码取反加1,即得到原始的二进制数(原码)。

附:可能很多小伙伴就有疑问了,一个数取反加1就得到它的补码,而该补码取反加1为什么又回到了原码呢?难道不应该是补码先减1再取反得到原码吗?其实这两种都对!但是后一种想法是咱们一贯的思路,在计算机系统内不能采取这种方法。前一种方法则是“补码”的精髓了,即补码的补码即为原码,大家需要去细品(我国的“阴阳”概念)!

博主小飞在这里多说一句:在位宽固定的情况下,补码和原码之和为0(舍去最高位进位)!

要点4:求一个二进制数的补码,除了取反加1外,还有一种非常快捷的实现方式。当我们看到一个二进制数,就能立马写出它的补码!

规则如下:从二进制数的最低位开始往左看,当遇到第一个1时,这个1左边所有位全部取反,1本身包括1右边的所有位保持不变,得到的结果即为补码。如下图所示:

dafcfcc69be945dc85b2ccfde7b6e0e4.jpeg

通过以上的介绍,我们知道了原码和补码之间的转换关系,但是这和负数有什么关系呢?且听博主小飞慢慢道来~

在任何计算系统中,必须能同时处理正负数。带符号二进制数含有符号和数值信息,符号指明这个数是正数还是负数,而数值就是该数的绝对值。

在二进制中,带符号数有三种表达方式:符号-数值、反码以及补码,其中补码是最重要的表达方式!

符号-数值表达方式:

最左边的一位是符号位,其余的都是数值位。数值位对正数和负数来说都是二进制原码(相当于数学中描述的绝对值)。例如:

十进制数+25表示为8位宽符号数的二进制形式就是:

ea0aeeabae8e4d6b81caa75a7809bd7e.jpeg

十进制数-25表示为8位宽符号数的二进制形式就是:

86791186c60b4feb9dcecbd056a20a92.jpeg

所以在符合-数值表示方式中,负数和其对应的正数具有相同数值位,唯一区别是符号位。

反码表达方式:

反码形式表示正数时,和符号-数值表达方式相同。但是反码形式表示负数时,负数却是其相应正数的反码。例如:

十进制数+25表示为8位宽符号数的二进制形式就是:

1d7a803052fb42918173b13ec51f175d.jpeg

十进制数-25表示为8位宽符号数的二进制形式就是+25(00011001)的反码:

11100110

补码表达方式:

正数的补码表达方式和符合-数值表示方法相同(也就是它本身),但是负数却是相应正数的补码。同样,使用8位数字,把十进制数-25表示成+25(00011001)的补码:

11100111

所以我们要明白,计算机处理负数时,要先把这个负数转化成其正数的补码后再进行下一步操作!负数在计算机内的表示方式不是符号-数值、也不是反码,只有补码!

 

现在我们知道:只要给出一个有符号十进制数,如果它是正数,则在计算机内它是按符号-数值方式表示;如果它是负数,则在计算机内按其正数的补码来表示。

 

那么,如果我们看到在计算机内部的一个8位有符号二进制数,比如01010110和10101010,我们如何得知它的十进制数是多少呢?博主小飞将介绍两种实用方法:

方法12次幂加权方法

在补码表达方式中,不管是正数还是负数的十进制值,都是把所有位相应2次幂表示的权加起来得到的,其中最高位的2次幂权为负。下面举例:

有符号数01010110的十进制值为:

cf401c727a7f4af48113ca4028ed58f2.jpeg

把所有位置为1的权加起来:

64 + 16 + 4 + 2 = +86

有符号数10101010的十进制值为:

1c3be19438c44f17b9b093deb8440ba4.jpeg

把所有位置为1的权加起来:

-128 + 32 + 8 + 2 = -86

所以对于补码形式而言,无论是正数还是负数,都使用同一套加权规则即可转化成十进制数,这也是补码的方便之处!

方法2:眼观法

首先看有符号二进制数的最高符号位,为0,则是正数,我们按照一般规则转换成十进制;为1,则是负数,我们按照上文中的要点3或4求其补码即可得其对应的二进制正数(也可称为原码),再按一般规则转换成十进制数,最后添加负号即可。

比如8位有符号数11111110是十进制数多少呢?如果我们按照方法1就会很麻烦,但是按照方法二,很快就能知道是-2.

 

正如上面所说的2次幂加权方法,我们知道了在补码表达形式的计算机系统里,有符号二进制数的最高位的权重应该是带负号。因此我们可以推算出,对于一个n位的有符号二进制数,其十进制数值范围应该是:

efcd0c3ec0ef4bbe804c187ccba49e15.jpeg

例如4位的有符号数,其范围为-8 ~ +7(1000~0111),共表示16个数。

例如8位的有符号数,其范围为-128 ~ +127(10000000~01111111),共表示256个数。

 

再次提醒小伙伴们,补码的概念和应用都非常重要,所有的负数都是用补码表示的!即使你现在还没用到补码,以后也肯定会碰到的,博主小飞现在把补码的重点都浓缩在这一篇博文中供大家参考,大家如果一遍不理解,就多看几遍噢~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值