【复制来的】http://blog.csdn.net/jjhua/article/details/50382563:连接;为了搞明白为什么8进制补码表示范围-128~+127,原码和反码表示范围-127~+127,也就是为什么会有-128的差别。
综合了But_Bueatiful博文 C语言关于补码的解释及误区 和百度知道计算机中补码的符号位可以不做特别对待而直接参加运算。求其证明过程。有些心得。
先抄一段博文里的内容用于理解模和补数的概念:
模、补数
在日常生活当中,可以看到很多这样的事情:
把某物体左转 90 度,和右转 270 度,在不考虑圈数的条件下,最终的效果是相同的;
把分针倒拨 20 分钟,和正拨 40 分钟,在不考虑时针的条件下,效果也是相同的;
把数字 87,减去 25,和加上 75,在不考虑百位数的条件下,效果也是相同的;
……。
上述几组数字,有这样的关系:
90 + 270 = 360
20 + 40 = 60
25 + 75 = 100
式中的 360、60 和 100,就是“模”(也可以理解成“进制”)。
式中的 90 和 270、20 和 40,以及 25 和 75,就是一对对“互补”的数字。
知道了“模”,求某个数字的“补数”,就是轻而易举的了:
如果模为 365,数字 120 的补数为:365 - 120 = 245。
用补数代替原数,可把减法转变为加法。出现的进位就是模,此时的进位,就应该忽略不计。
二进制数的模
前面说过的十进制数 25 和 75,它们是 2 位数的运算,模是 100,即 1 的后面加上 2 个 0。
如果有 3 位数参加运算,模就是 1000,即 1 的后面加上 3 个 0。
这里的 1000,是十进制数的一千,可以写成 10^3,即 10 的 3 次方。
推论:有多少位数参加运算,模就是在 1 的后面加上多少个 0。
对于二进制数字,模也是这样推算。
如果是 3 位二进制数参加运算,模就是 1000,即 1 的后面加上 3 个 0;
那么当 8 位二进制数参加运算,模就是 1 0000 0000,即 1 的后面加上 8 个 0。
16 位二进制数参加运算,模可就大了,是 1 的后面加上 16 个 0。
注意:这里提到的 1、0,都是二进制数。
8 位二进制数的模可以按照十进制写成 2^8,即 256。
16 位数二进制数的模,就是 2^16,按照十进制,它就是 65536。
再抄一段百度知道内容用于理解如何快速计算负数的补码
可以想像一下,有个小孩子,很小,不很识数,只认识 0 ~ 99,还不会做减法。
教这样的小孩做减法,就可以告诉他:-1,可以用+99来代替。
24 - 1 = 23
24 + 99 = (1)23
忽略进位,是不是就是一样的?
那么,98,就是-2;
97,就是 -3;
……
50,就是 -50。
看明白这些,就可以理解了《补码定义式》。
--
对于八位的二进制数,是 0 ~ 1111 1111(255);
255,就是 -1;
254,就是 -2;
……
128,就是-128。
这就是按照《补码定义式》,求出来的《负数的补码》。
而 0~127,按照《补码定义式》,就是《正数的补码》。
总结:
所以存在补码定义式:
[X]补 = X 当 X 大于等于0 时
[X]补 = 模 - |X| 当 X 小于 0 时
举例说明:
八位二进制 ,注意:没有符号位,全部作为数据位,则最大值为八个1即 1111 1111B,那么模即为 1 0000 0000B,也就是最大值+1,十进制值为256
零和正数的补码即为十进制转为二进制的结果,如0 的补码 0000 0000B ,+127的补码 0111 1111B
负数的补码即为 负数的补数 的二进制形式,负数的补数=模-|负数|
举例求-3的补码:
-3的补数=256-3=253 ,转换为二进制1111 1101,此即为-3的补码。
可以通过书上讲的原反补过程验证一下,-3的原码是1000 0011 ,反码是除符号位以外取反结果为1111 1100 ,补码是反码+1,最终结果即为1111 1101,与上面结果一致。
做两个算术运算:
假设前提8位二进制。
分别计算 5-3 和 3-5 两个式子结果,结果用补码表示。
5-3 即为 5+(256-3)= 258 = 1 0000 0010B,抛弃超出的高位1,结果为 0000 0010B,很明显为2的补码
3-5 即为 3+(256-5)= 254 = 1111 1110B,按书上原反补计算方法,-2原码1000 0010B 反码1111 1101B 补码1111 1110B,一致。