数学专栏课外加餐(一) | 我们为什么需要反码和补码?
数学专栏课外加餐(一) | 我们为什么需要反码和补码?
讲述:黄申
时长10:32大小9.62M
什么是符号位?为什么要有符号位?
二进制的原码、反码及补码
赞 7
提建议
精选留言(102)
- 奔跑的蜗牛置顶2019-04-27疑问1:为什么i-j得加上取模的除数? 疑问2:2^n-1就是32位1,这个地方就又没有符号位之说了? 疑问3:非符号位计算溢出会进到符号位嘛? 麻烦老师帮忙解答下
作者回复: 我分别来回答一下 疑问1:这个还是要回到计算机只有累加器、没有累减器的本质。因为只有累加器,那么我们如何才能实现减法呢?人们巧妙的利用了计算机的数值是有范围的(无法表示无穷大),从而通过加法来实现减法。核心思想就是通过加上一个取模的除数,这样(-j)+取模的除数正好形成了溢出,达到了减法的效果 疑问2:我们只考虑(n-1)位的1,不考虑第一位 疑问3:这取决于数据是有符号还是无符号的,如果是无符号的数据类型就不存在这个问题。如果是有符号的数据类型,非符号位可能溢出到符号位,这也是为什么对于有符号的数据类型,过大的数据反而会变成负数。
4 - xzy2019-01-02为什么负数的补码等于反码加一 1,基本概念(看看了解一下就好) 计算机通过将最高位设置为符号位来表示正负数: 符号位为1时,代表这个数为负数;符号位为0时,代表这个数为正数。 为了方便理解,本文中的例子全部用4位二进制数举例 原码:除符号位外的其他位,保存该二进制数的绝对值。 例如 1:0001 -1:1001 反码:正数的反码等于原码; 负数的反码就是其原码除符号位外,按位取反。 例如 1:0001 -1: 1110 补码:正数的补码等于其原码 负数的的补码等于反码加一 例如 1:1001 -1:1111 2,原码、补码 原码、反码、补码都可以通过符号位非常方便的表示正负数,但是在进行加法计算时,原码和反码都存在这样或那样的问题: 注: 计算机cpu的运算器只实现了加法器,而没有实现减法器,计算机是通过加上一个负数来做减法的 原码: 1 + 1 = 0001 + 0001 = 0010 = 2 1 + -1 = 0001 + 1001 = 1010 = -2 从上面的计算可以看出,原码无法通过加上一个负数来实现减法 反码 1 + -1 = 0001 + 1110 = 1111 = -0 1 + -2 = 0001 + 1010 = 1011 = -4 从上面的计算可以看出,反码也无法实现加上一个负数来实现减法 原码和反码都不能解决的事情,只有通过寻找一种可以完美支持件“减法“的二进制数的表示方法来解决! 3,补码 一个4位的二进制数能表示的数是有限的,从 0000 ~ 1111 ,0000表示0,1111表示 - 1,最大值7(0111),最小值-8(1000)。 看下面这组计算: 0000 + 0001 = 0 + 1 = 0001 = 1 0001 + 0001 = 1 + 1 = 0010 = 2 0010 + 0001 = 2 + 1 = 0011 = 3 ... 0111 + 0001 = 7 + 1 = 1000 = -8 1000 + 0001 = -8 + 1 = 1001 = -7 1001 + 0001 = -7 + 1 = 1010 = -6 ... 1111 + 0001 = -1 + 1 = 0000 = 0 0000 + 0001 = 0 + 1 = 0001 = 1 0000 每次加上 0001 ;当最大值7 + 1时,正溢出,结果为最小值-8;最小值-8加上8后,又变成了0000,就像钟表一样,循环往复。 比如说现在有一个数字2,我们想让它变成0,怎么办? 有两种方法: 1. 减去 2 个 1 即:0010 - 0010 = 0000 2. 加上 14 个 1 即:0010 + 1110 = 0000 我们可以总结出,当一个四位的二进制数abcd 减去 另一个四位的二进制数 efgh : abcd - efgh = abcd + (1111 + 1 - efgh) 。 efgh 和 (1111 + 1 - efgh) 对模 (1111 + 1)同余。 如果不太理解,就可以想象一个钟表的时针停在10点的位置,如果想让时针停在8点的位置,可以逆时针的旋转2个刻度,也可以顺时针的旋转10个刻度。 通过公式abcd - efgh = abcd + (1111 + 1 - efgh) ,我们可以得出,如果计算机使用(1111 + 1 -efgh)来表示 -(efgh) ,就可以解决减法的问题。这就是我们补码的原理。 由于1111 - efgh 等于 efgh 的反码 ,所以 efgh 的补码等于 efgh的反码加上1。展开共 2 条评论84
- 老板来几袋面粉2018-12-24好复杂,开始慌了共 3 条评论54
- 梓航(﹏)2018-12-24老师,你讲的那个取模和反码的关系那一段我看不懂,之前看书也没有遇到你说的这种概念,请问还有其他学习资料吗?
作者回复: 其他的材料一般都没有将“为什么”这么算说清楚,我画了张图,你结合图来理解。简单的说,你可以认为a-b的减法就是给a加上一个特别大的数,导致溢出,然后剩下的反而比a小,这就达到了减法的目的
30 - 随欣所遇2019-04-12用大家熟悉的一周七天进行对比吧 1、计算数据的溢出相当于模:假设第1天为周一,第2天为周二,以此类推第7天为周日,第8天已经大于7溢出了,8对7进行取模为1,也即第八天为周一;取模的除数为上限减去下限+1,替换过来换算:一周的上限为7,下限为1,那一周取模的除数换算为:7-1+1,所以我们想要知道第15天后是周几直接对(7-1+1)取模即可; 2、i-j=(i-j)+(2^n-1+1)=i+(2^n-1-j),可以换算为 周一 = (周一)+ (7-1+1)进行理解(ps:不一定周一,周几都为同一样,只是将 i-j 看成一个单元用其做概念上的替换)展开
作者回复: 是的
共 2 条评论19 - 石佳佳_Gemtra2018-12-24思考题: 原码:10100010 对补码除符号位取反得 反码:11011101 +1操作得 补码:11011110 对应十进制数:-94 还有一种方法,把负数原码除符号位外求和,减去 (2^n-1+1),即 2+32-(2^7-1+1)=-94展开
作者回复: 是的
共 4 条评论19 - 风轨2018-12-24思考题 0b10100010 = 0b10000000 + 0b00100010 其中 0b10000000 = -128 0b00100010 = 34 所以答案是 -94 2进制取相反数公式 相反数 = 原数减一再取反 - 0b10100010 = !(0b10100010-1) = 0b01011110 = 94展开
作者回复: 是的
11 - 二十八画生2019-01-02本文重要的是说清了补码的由来,为啥这样定义补码7
- Temme2019-06-19思考题:10100010 如果是原码,所对应的数字就是-34 如果是补码,那么就减一取反求原码,11011110,就是-94。 然而对着补码再去求一次补码也可以得出原码,所以神奇的是某个回答也是对的。。。这就是所谓的互为补码。展开
作者回复: 对的,负负得正的原理
6 - 恒2019-06-18补码代码的数值的快速求法 负数补码通过非符号位0出现的位置来计算,然后计算结果加1,最后带上符号即可。 比如 1000,非符号位为000,按照0出现的位置计算,000=2^2+2^1+2^0=4+2+1=7,结果加上1后得到8,所以这个二进制数 表示-8 正数补码看非符号位1出现的位置来计算,然后加上符号即可。 比如 0111,非符号位为111,按照1出现的位置计算,111=4+2+1=7 所以这个二进制数 表示+7 对补码的理解: 目的:为了使用相同电路来实现加减运算,使得计算机cpu设计更加容易 为何用补码,可以通过如下四位数模拟补码从0开始一直加1的情况 0000 = 0 0001 = 1 0010 = 2 0011 = 3 0100 = 4 0101 = 5 0110 = 6 0111 = 7 1000 = -8 1001 = -7 1010 = -6 1011 = -5 1100 = -4 1101 = -3 1110 = -2 1111 = -1 0000 = 0 (再加1又从0开始了,上面表示的不同数值的个数是2^4=16,所以模是16) ... 然后上溢和下溢也顺便理解了,如下所示, 上溢就是4位二进制数的正数的最大值加1,然后通过补码加法运算后结果是4位二进制数的最小数-8 上溢:7 + 1 =0111+0001=1000(4位二进制数的最小数)=-8 注:加上1的目的是最大值再大一点,当然就溢出了 下溢就是4位二进制数的负数的最小值加-1,然后通过补码加法运算后结果是4位二进制数的最大数+7 下溢:-8+(-1)=1000+1111=0111(最大数)=7 注:加上-1的目的是最小值再小一点,当然就溢出了展开
作者回复: 很详细的解释
6 - 彩色的沙漠2018-12-26老师,不好意思 问题有一处错误,我纠正一下,以免误导后来的同学 java中int的最小值是-2^31 二进制源码:1 000 0000 0000 0000 0000 0000 0000 0000 二进制反码:1 111 1111 1111 1111 1111 1111 1111 1111 -2^31的补码还是自己,符号位进位舍弃展开
作者回复: 是的👍
6 - 夏飞2018-12-25这不就是余数和取模的概念吗? 这句话不明其意
作者回复: 可以将问题简化一下,假设计算机的数据类型只有正数,而超过100就溢出了,那么102就好比2。这就好比对100取模,2和102的余数是一样的
5 - 爱吃锅巴的沐泡2019-06-26老师,请教一下问题 文章中讲的是原码到补码的推导过程。 一个二进制数在计算机中存储的形式就是补码。 那么一个数输入到计算机中就是补码形式,还是说有一个从原码到补码的推导过程?可是这个推导过程中也有减法,和补码把减法加法化的说法就冲突了?
作者回复: 计算机存储的就是补码,这个推导过程是便于人的理解
4 - 吾本糊涂2018-12-2510100010直接用10进制表示不是-34吗 为啥要去它的补码再换算10进制?
作者回复: 负数在计算机中用补码表示,你可以先算算-34的补码是多少
3 - 吉祥2018-12-24以为是-34呢😂3
- mickey2018-12-241010 0010 除符号位取反 -> 1101 1101 加1 -> 1101 1110 转十进制 -> -943
- 江宁猎妈人2020-03-18以前学计算机原理的时候,一直想不明白为啥补码这么设计,虽然也知道是取余,但一直没很清楚的推导过。这次看了文章更有体会。拿 4 位 2 进制数举例,-2 原码 1010,补码 1110,相当于 -6 的原码 ,也就是 -6 = -8 - (-2),而 -8 正是一个循环。给 -6 加 1,1110 + 0001 = 1111 (-7), -7 还原以后就是 - 1 = -2 + 1;继续下去 1111 + 0001 = 1/ 0000 = 0,这样就转回来了。 同样的,这也是补码 1000 代表 -8 的原因。 和上面一样,1001 是 -7 的补码,也是 -1 的原码。再减一位,变成1000 ,若用原码表示法,就是 -0,和 0000 都是 0,浪费了一个数。若以补码的思想,-8 - 0 = -8,这样摇身一变,就使得表示范围多了一位,弥补了 2 ^ n 的边界值。展开
作者回复: 是的,很好的总结
2 - Rainbow2018-12-27“其中 2^n-1 的二进制码在不考虑符号位的情况下是 n-1位的1“ 这个地方不理解,2^n-1的符号位不是0吗? 而2^n - 1是有位的1啊。 这个地方不理解,希望老师能解答一下~
作者回复: 对于有符号的数据类型,2^n-1是n位1,但是第一个是符号位,所以符号位是1
2 - Modern2018-12-27想了好久好久,想通了几点,老师看下~ 1.计算机中,用补码来表示负数,方便计算 2.但是,原码才是人类可识别的 3.将补码转换为原码,有2种方式,一种是取反后加1,另一种是减1后取反,其实本质上是一样的,借助于取余的思想就好理解多了2
- 毕明亮2018-12-24老师,评论里石佳佳说那个是源码取反加一,Li Shundong又说是补码取反加一得源码……看晕了
作者回复: 其实两者是可以这样互换的,这样思考可能更简单一点:(2^n-1-j原+1)=j补,那么j原和j补分别移到等号的另一边,就是(2^n-1-j补+1)=j原,2^n-1-j补就是去j补码的反码,然后+1就是j原码
2