首页
论坛
课程
招聘
理解补码,我用另外一种脑回路
2020-12-25 18:00 3263

理解补码,我用另外一种脑回路

2020-12-25 18:00
3263

    今天突然想求个补码,但不记得取反后应该+1,还是-1了,于是搜到这篇文章:https://blog.csdn.net/wenxinwukui234/article/details/42119265

    有些人学东西,主要靠记忆,而有些人主要靠理解,有些人两个方面都很强。我猜这位博主,主要靠理解,要不然不可能对记住"取反加一"四个字,这么没自信,哈哈哈!这其实很正常,比如我就记不得是加1,还是减1了,上完小学后,记忆力一直在退化,以至于初中高中从来不背诗,英语也学不好,导致工作后为学英语花了好多钱,但也还是个渣渣!

    这篇文章写的很有意思,提出了补码的本质作用:为了让+M和-M的二进制,经过加法器运算得到的是0。而且看得出来,博主喜欢用数学的思维想问题,我也津津有味的看完了,同时也发现一种更容易理解的方法。

    假设+M的补码为:xxxxxxxx, -M的补码为:yyyyyyyy,那么它们相加要等于0才行:

   xxxx xxxx
 + yyyy yyyy
--------------
   0000 0000

    先不要认为xxxxxxxx和yyyyyyyy互补,而是互为相反数,那么:

   xxxx xxxx
 + yyyy yyyy
--------------
   1111 1111

    推导出:

(xxxxxxxx+1) + yyyyyyyy = 0
xxxxxxxx + (yyyyyyyy+1) = 0

    也就是说,不管对于xxxxxxxx还是yyyyyyyy,加上它们的(反码+1),就可以等于0

    我的思路跟这位博主的出发点是反的,然后0的补码为什么还是0,以及char类型中,-128不存在+128跟它补的原因,就清楚了:

   0 -> 反码: 11111111 -> 加1得到补码:100000000,最高位溢出,结果仍为0
-128 -> 反码:01111111 -> 加1得到补码: 10000000,符号位为1,结果仍为-128



第五届安全开发者峰会(SDC 2021)议题征集正式开启!

收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 3367
活跃值: 活跃值 (930)
能力值: ( LV9,RANK:145 )
在线值:
发帖
回帖
粉丝
天水姜伯约 活跃值 3 2020-12-28 13:16
2
0
说来我也是近期基本概念忘得一塌糊涂。一个同学问我一道大学计算机基础上的溢出标志位判断题,我愣了半天硬是想不起啥是溢出,最后还是查wiki解决的
雪    币: 4180
活跃值: 活跃值 (1829)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
jmpcall 活跃值 1 2020-12-28 18:56
3
0
哈哈,你提到溢出,让我想到CF、OF标志位,进一步发现自己一个错误:
求反码和补码,都不会影响符号位(反码计算,不会取反符号位,补码计算,会丢弃次高位的进位),所以帖子中对0和-128反码和补码的描述,是错误的!8位二进制,能表示的原码和反码范围,都为-127~127,表示不了-128!0的反码和补码,也不是帖子中那样算的!
那么,-128没有8位二进制的原码和反码,为什么却有补码(10000000)呢?而且,按照"取反+1"的计算过程,10000000也应该是-0的补码才对啊(10000000->11111111->10000000) ?
答:对于人类的大脑来说,-0、+0都为0,所以没必要占用2个补码,统一用+0的补码00000000即可(00000000->01111111->00000000),同时,想象一个128刻度的圆盘,由于向反方向转一圈(-128),和留在原地不动(-0),效果是一样的,所以就将10000000作为-128的补码。
但是,CPU怎么会想这么多呢,它只会麻木无情进行0和1相加操作,所以怎么让它区分补码10000000,代表-0,还是-128呢?这很重要的,10-0等于10,10-128可就是-118了啊。
答:以0刻度为基准,10(补码:00001010)和-118(补码:10001010),对应相同的刻度,但是,00001010+00000000得到的就是00001010,而00001010+10000000得到的就是10001010,相应也就很容易理解,单纯从位置上考虑,补码10000000对应0和-128,甚至还有+128、-256等等,但由于符号位和数值位共同的约束,决定了它只能是-128。
不过以上分析也更加说明,通过刚正面的方式去想补码的由来,很容易犯糊涂,而顺着补码设计的目的去想,就会很容易:对于M和它的反码N,由于它们每一位都相反,所以M+N的每一位就都为1,再加1,就会溢出得到0,从而将(反码+1)作为补码,就这么简单。更准确的说,补码是为了让+M与-M的数值位相加等于0,这也是计算补码,不影响符号位的原因。
理解了补码,CF、OF也会相应好理解一些了,无符号数相加是否溢出,通过CF判断,有符号数相加是否溢出,通过OF判断,以及CF、OF为什么要这样算:
CF = 最高位是否进位(进位1,否则0)
OF = 次高位是否进位(进位1,否则0) ^ CF标志位
现在大家都在呐喊学以致用,我觉得学以致用也分长线和短线吧,有些东西虽然不是直接拿来用的,但它可以保证使用相关东西的时候,不犯糊涂,熬过一个阶段后,应该会比只停留在表面,轻松一些吧
游客
登录 | 注册 方可回帖
返回