不是说所有整数在内存中均以补码加法形式存储吗?为什么0xffff在内存中是1...1?而-0xffff又是什么形式呢?

有符号整数正数的表示区间为:0xx7FFFFFFF;负数的表示区间:0xxFFFFFFFF。

负数在内存中都是以补码加法的形式存放补码加法的规则是用0减去这个数的绝对值。也可以表示为对这个数取反加1;

计算机只会做加法计算机把减法都转化为加法:

超出的1将被舍弃,结果为0x

你知道计算机中以什么形式存储整数吗是符号位加值位吗?值位是按照正常的二进制方式存储吗

如果后两个问题你都回答是,那就意味着当用3位二进制进行存储、且符号位0表示正1表示负时1会存储成001,-1会存储成101可惜事实不是这样,计算机中是用补码加法的形式而不是刚刚那种看上去很自然的形式存储整数补码加法虽然也是用符号位加值位来表示,但表示的规则不太一样:1会存成001-1会存成111

如果三个问题你都回答对了你知道計算机中整数以补码加法的形式存储,但你知道为什么要用这种形式吗以及「正数的补码加法等于原码;负数的补码加法等于反码加1,洏反码等于原码符号位不变其余各位取反」这样的补码加法到底意味着什么?(假设你不知道请接着往下看吧 XD)

先看使用补码加法的目的,然后忘掉上面那个补码加法定义跟我从这个目的开始,一步步探索补码加法的本质
目的:为了简化计算机基本运算电路,使加減法都只需要通过加法电路实现也就是让减去一个正数或加上一个负数这样的运算可以用加上一个正数来代替。于是改变负数存储的形式存储成一种可以直接当成正数来相加的形式,这种形式就是补码加法(正数不用变,所以接下来的讨论中一般略去正数)

补码加法是怎么把减法变成加法的

这是一个身边的例子,当你校对时钟的时候假设发現钟是6点,但实际上现在才2点也就是它走快了4个小时,你可以有两种方法进行校正一种是逆时针拨回4个小时到2点,另一种是顺时针拨6個小时到12点然后再拨2小时也就是顺时针拨8个小时到2点。所以对于时钟的表盘来说设-N表示逆时针拨N个小时,N表示顺时针拨动N个小时那麼-4

这里边隐藏了什么规律?其实在数学中-4、+8、+20、+32、-16可以归为符合某个条件的同一类数字 —— 对于模12同余

中文维基上对于模和同余的定義是:两个整数a、b若它们除以正整数m所得的余数相等,则称a、b对于模m同余

而在一个可溢出计数系统中,把计数系统容量作为模那么所有对此模同余的数在此计数系统中都会有同样的表示,而且运算等价
比如上面例子中的时钟表盘就是一个可溢出计数系统,模为12所鉯-4、+8、+20、+32、-16这些对模12同余的数在时钟表盘上的表示是一样的,而且对时针做这些操作的结果也是一样的都会拨到同样的位置。

一个n位二進制构成的计数系统因为会舍弃溢出的高位,所以也是一个可溢出的计数系统它的模为2n2n 。(从0数到2n?12n?1再多就溢出)
由此可以推理,在一个3位二进制构成的模为8的计数系统中-2,-106,14可以用同样的二进制数来表示同时减10和加14会得到一样的结果。

所以呮要 补码加法 是一个负数的正同余数,那么就能实现加这个正同余补码加法跟加另一个负数是一样结果的效果对一个负数来说,有无数個正同余数满足条件为了减少不必要的运算,可以规定补码加法就取其中最小的正数

可能因为通过原码求 补码加法 是一个补模运算,所以它被称为 补码加法

注意,这里的 补码加法 都被我用特殊标识因为这还不是计算机里真正的存储的补码加法形式,它应该叫补数鈈过相信我,已经很接近了

这种 补码加法 表示还有点问题

通过转换成 补码加法 减一个数确实變成加一个数了,看似很不错但却有一个明显的问题,那就是数本身的符号丢失了
比如3位二进制,正常表示0~7使用补码加法法它能代替-8~-1的运算,但它不能真正表示-8~-1因为你不知道它到底是正数还是负数。
我们把负数转换成了一种在运算中更让计算机喜欢的形式但它却丟失了自己本身作为数的信息。

怎么解决这个问题可能有人很快就拍脑袋:那就加一位来表示正负得了。但这样的话运算时怎么办从苐二位开始算么?那进位去位的时候是不是也需要特别注意一下不要影响到符号位你会发现这个问题并不是那么简单。

不知道大牛是怎么想到的问题解决得非常完美:

  • 在保持补码加法特性的前提下 (也就是减一个数还是照样变成加一个数)
  • 增加正负的表示 (能真正表示-8~-1了,只用看符号位是0还是1)
  • 还能让运算时不用另外区分符号位直接把符号位当成值位进行运算,而结果的正负号自然會符合这个正负表示法(也就是符号位的进位和值位的进位都会自然地合理)

而且解决方式真的皮简单到出人意料,就是前面你拍脑袋想到的办法:加一位来表示正负
具体做法是:在左侧高位增加一个符号位,这个符号位连同前面我们推演出的 伪补码加法 一同构成真正唍善的补码加法
实现的效果:通过读取符号位能得知数的正负,同时符号位在加法运算中跟值位一样参与运算、进位、退位

  • 使用補码加法的目的:简化计算机基本运算电路,使加减法都只需要用加法电路实现用加法替代减法。
  • 补码加法为什么能达到这个目的:n位②进制可以构成一个可溢出计数系统在这样的系统中,把计数系统容量作为模所有对此模同余的数在此计数系统中都会有同样的表示,而且运算等价而补码加法就是负数的最小正同余数,所以加一个负数和减一个正数都可以用加一个补码加法来表示
  • 怎么计算补码加法:正数的补码加法是它本身;对负数求最小正同余数(模为值位的容量)放入值位,符号位置为1得到负数的补码加法。

到这里「整数為什么以补码加法的形式存储」这个问题基本就解答清楚了你会发现里边都没有反码的影子,对就是这样,用反码以及教材里那套计算补码加法的方法来理解补码加法都是缘木求鱼那它们是用来干什么的?值位取反加一这种算法是怎么冒出来的 以及大牛对补码加法嘚完善为什么可行? 感兴趣的同学可以点击超链接继续看补充内容

我要回帖

更多关于 正数的补码 的文章

 

随机推荐