文章标题用补码不是很合适,但是目前自己还是比较乱,没理出什么头绪来。
先明白一个关系:在计算机系统中,机器码到底是独以补码的形式保存数据或字符,还是原码补码兼而有之。
何为带符号数?何为不带符号数?
如果是带符号数那就包括 "+","-"罗,为保存符号必须腾出一位用来专门保存。
如果是无符号数,就是默认为正数,所有的分配位都仅仅是用来存储数值的。
那么补码是专门针对有符号数而设置的还是怎么的?
为什么要设立补码呢?
书上如下解释:
第一是为了能让计算机执行减法:
[a-b]补=a补+(-b)补
第二个原因是为了统一正0和负0
正零:00000000
负零:10000000
这两个数其实都是0,但他们的原码却有不同的表示。
但是他们的补码是一样的,都是00000000
特别注意,如果+1之后有进位的,要一直往前进位,包括符号位!(这和反码是不同的!)
[10000000]补
=[10000000]反+1
=11111111+1
=(1)00000000
=00000000(最高位溢出了,符号位变成了0
我对于正0负0我可以理解,但是上面说的统一了加减法,这就有点纳闷,不太理解。
OK,加减法的统一我开始理解了。加法还是和以前一样做,只是减法便的不一样了,应用补码,则只需做加法这一种操作。
例:设a,b都为正数,a-b=a+(-b);如果我们之前没有补码这个概念,那么就意味做我们必须做减法操作,减法就涉及到借位,这很麻烦。现在有了补码就好了啊,你看a-b=a+(-b),a减b的运算就成了a和-b之间的加法运算。
说起来有点饶舌,呵呵,只是自己以前总是不理解补码为什么就统一了加减法了呢。现在发现是忘了一个条件,理解的时候应该假设没有补码会怎么样,有补码了又怎么样?以前直接搞混了,根本就没有把补码的概念抛出去,所以一直就很混乱,理不清思路。
现在在抄录一段书上的原话:
1.如果符号相异的数要进行相加或两个同符号数进行相减,则要做减法运算。做减法运算会产生借位问题,很不方便。为了将加法和减法运算统一起来,以加快运算速度,引进了数的反码和补码表示;
2.引入补码以后,加法和减法运算都可以统一用加法运算来实现,符号位也当作数值位参与处理。
3+(-2)按补码进行运算 0000 0011 + 1111 1110 =0000 0001事实证明是正确的,把符号位也加进来做运算
而且还有一个问题,书上说原码表示整数的范围是-(2^(n-1)-1) ~ +(2^(n-1)-1);
补码表示整数的范围是-(2^(n-1)) ~ +(2^(n-1)-1);
这个我也不太明白。
这一点我现在是可以明白了
原来的+0和-0被统一成0,就多出了一个可以表示数值的组合1000 0000
这个组合如果是补码的话,那么他的原码就是 1 1000 0000
演算如下:
(1000 0000)原 = -((000 0000)反+1) = -(111 1111 +1)=-(1000 0000)=-128
补码代表的值不是内存中保存的值,例补码 1000 0010表示的并不是-2而是-((000 0010)反+1)=-(1111101+1)
=-(111 1110)=-126;
至此明了,我以前居然傻到依然把补码当成原码看待。
//////////////////////
00000000减1应该等于11111111
00000000-1
= 00000000 + (-1)
= 00000000 + 11111111
= 11111111
为什么-1的补码是11111111
因为补码就是“取反加一”。1是00000001,取反11111110,加一11111111
上述一段话中的"取反加一",一开始还想不通,因为书上说的是原码除去符号的的取反加一。
现在想明白了。
+1的原码0000 0001 直接取反 1111 1110
-1的原码1000 0001 除去符号位的取反 1111 1110
两者结果是一样的。晕倒,网友们自创的"取反"还真是让我费解啊。不过这种方式更方便心算。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
上述如果有什么错误之处还望过往之人指点,有些错误自己很难发现。