在线咨询 切换到宽版
eetop公众号 创芯大讲堂 创芯人才网

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜全文
查看: 29198|回复: 42

[求助] 关于补码的加法和乘法运算

[复制链接]
发表于 2011-5-31 21:44:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
本帖最后由 larlyii 于 2011-5-31 22:14 编辑

小弟我最近被一个问题纠结好久,就是有符号,无符号数,原码补码之间的运算,比如举个例吧,-6和7,我去算它们之间的加法和乘法。
假设输入数据用8位2进制表示。

首先,-6的原码是10000110,补码是11111010;7的原码是00000111,补码同样(因为是正数)
加法:加出来有9位:100000001,如果我们只取低8位,就是00000001,为十进制的1,答案正确。但是好多书上写的代码都是把加法器的输出扩展了一位的,那就是说,这个数的十进制表示变成了-255,明显不对~

乘法:乘出来有11位:11011010110,直接取的话肯定不对,但是如果只取低8位的话是11010110(补码),即十进制的-42,就正确。但是一般为了避免溢出,我看好多书上都是把乘法器的输出位宽扩展成输入的2倍,那这样输出又和上面的加法同样的由于扩展位宽而出现的错误。

按照以上逻辑,岂不是我设计的模块的输出必须和输入有同样的位宽?但实际情况显然不是,不知这是怎么一回事?

现贴上ModelSim的图为证:

十进制

十进制
十进制的

二进制

二进制
二进制的
发表于 2021-6-18 11:17:53 | 显示全部楼层
学习中…………
回复 支持 反对

使用道具 举报

发表于 2021-6-16 15:03:26 | 显示全部楼层
多谢楼主和各位的分享,解决了困惑我好久的问题,受益匪浅!
回复 支持 反对

使用道具 举报

发表于 2021-6-16 15:01:09 | 显示全部楼层


   
glace12123 发表于 2018-1-5 21:37
你对有基2补码的理解是错误的。。。。2个N位的有符号数相加,必须各自扩展符号到MSB上形成2个N+1位数相加, ...


感谢,解释的好清楚,解答我的困惑了!
回复 支持 反对

使用道具 举报

发表于 2019-5-26 23:19:01 | 显示全部楼层
带符号的乘法运算,符号位异或计算,然后转化为原码用于乘法计算,最后得出的结果再转换为补码
回复 支持 反对

使用道具 举报

发表于 2018-5-22 10:12:20 | 显示全部楼层
Thanks
回复 支持 反对

使用道具 举报

发表于 2018-5-11 14:43:07 | 显示全部楼层
回复 7# dlb05061131

偶然看到你这个文件,解决了设计中困惑很久的一个问题,非常感谢!
回复 支持 反对

使用道具 举报

发表于 2018-4-12 01:26:54 | 显示全部楼层
补充一点,之所以要按照我上面说的原则发明补码,是因为数字电路其实是很蠢的。他并不知道你的数是有符号数还是无符号数,我们需要让电路在进行加法或乘法运算时,不论你给的是有符号数、无符号数、正数或是负数,他的映射规则都一模一样。
回复 支持 1 反对 0

使用道具 举报

发表于 2018-4-12 01:16:50 | 显示全部楼层
初学者很容易把补码的意义理解错误,我来试着给你解释一下。
看上面很多人讨论的时候,其实把好几个概念混在一起了。其实我觉得应该分开来讲。
1.补码的意义
其实我理解的补码的意义很简单,就是认为地创造一种二进制编码,使得两个有符号的补码相加或相乘的时候,在位宽能够装得下你的计算数的前提下,可以直接忽略溢出位。
如何能做到这样呢?其实很简单。我们拿加法来举例吧,这样比较简单。
我们假设有一个4比特的二进制数,如果我们要用他来表示有符号数。
比如6应该是0110,那如果我要如何在能满足我前面提到的要求的前提下,来表示-6?
即X+6=0+16。16是2的四次方,既然现在只有四比特,那两个数相加肯定只能再往上溢出1位。如果我们把这个溢出位忽略掉,那就相当于减去了16。所以我们用1010(十)来表示4比特有符号数-6。你可以用补码取反加一的方法去验证每一个数。如果是五比特有符号数,那溢出位忽略掉的就是32了,依此类推。
2.为什么要扩位?
其实扩位跟补码的运算法则没有半毛钱关系的。我上面说了,补码之所以要发明,就是为了两个数在相加时可以直接忽略溢出位。可以直接忽略,那为什么我们平时要扩位呢?
我前面说到了,加法运算的时候,我们需要考虑到数相加之后的你给的位宽能装得下你的结果。比如,一个4比特的有符号数,能表示的范围是-8~7。那如果两个4比特的有符号数相加,范围就是-16~14。这样的范围的数四比特是装不下的,必须要五比特才能装得下。所以为了防止这种我们不期望的溢出发生,就需要在相加之前先扩成五比特。但是如果你这两个数虽然是四比特,但其实你清楚他并不可能把范围用完,比如你只用到了-2~2,那你也可以不用扩位。
总之,作为一个数字电路设计工程师,心里必须要随时有一个很清晰的账本,每一个数的取值范围是多少。你在定义每一个数,在做每一次运算的时候都要确保你能装的下他。
3.如何扩位
当一个数你已经发现了在加法或乘法之后,当前位宽装不下了,那你要如何扩位呢。如果是无符号数或者有符号的正数,那很简单,直接高位补0就行了。
如果是负数,其实也很简单,就是理解上稍微麻烦一点。你可以仔细看我第一条负数的补码的推导过程。如果有一个数-N,四比特表示的方法就是16(2的四次方)-N。你现在要扩成五比特,那就需要表示成32(2的五次方)-N。没错,扩展的过程中,其实就是要加上2的四次方即可。这就是你一直被告知的原则,负数扩位高位补1。
我上面说的原理同样适用于乘法,有兴趣的话你可以自己去推,其实思路都是一样的。了解了这些,相信楼主不会再在理解补码时这么混乱了。
回复 支持 1 反对 0

使用道具 举报

发表于 2018-3-17 08:47:49 | 显示全部楼层
学些了,谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


手机版| 小黑屋| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-9-19 19:45 , Processed in 0.022670 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表