因为是“半路出家”,从来没有看过《计算机组成原理》这种书籍,感觉这方面的知识十分欠缺。网上对原码、反码、补码的解释很多,也基本都是一样的。但是我觉得还是难于理解。就想谈一下自己的看法,还请大家多多提出意见,让我们大家都有所裨益。
在这里,原码、反码、补码的那些看起来就头晕的公式就不再列出了。我想大家也都不愿意去看那些公式,更不愿以去背记他们。所以先把基本的原码、反码、补码的含义先给列出来:
原码:
如果机器字长为n,那么一个数的原码就是用一个n位的二进制数,其中最高位为符号位:正数为0,负数为1。剩下的n-1位表示概数的绝对值。
例如: X=+101011 , [X]原= 00101011 X=-101011 , [X]原= 10101011
位数不够的用0补全。
PS:正数的原、反、补码都一样:0的原码跟反码都有两个,因为这里0被分为+0和-0。
反码:
知道了原码,那么你只需要具备区分0跟1的能力就可以轻松求出反码,为什么呢?因为反码就是在原码的基础上,符号位不变其他位按位取反(就是0变1,1变0)就可以了。
例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100
补码:
补码也非常的简单就是在反码的基础上按照正常的加法运算加1。
例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]补=11010101
PS:0的补码是唯一的,如果机器字长为8那么[0]补=00000000。
可以看出,
反码就是在原码的基础上,符号位不变,其他位按位取反得到的;而补码就是在反码的基础上按照正常的加法运算加1。估计网上这种解释多了去了,但是不知道大家有没有想过,为什么要有反码、补码这些呢??
这个问题大家可以参考这篇博客:
http://blog.csdn.net/love19840109/article/details/4552820
而我想表达的内容是:反码为什么是原码按位取反,补码又为什么是按位取反后加1!
先讲个常识引入我们的问题:
假如我们有个钟表,现在是7点钟,而真实时间是4点钟。那么我们有两种方法去校正时间:
1.逆时针拨动时针3格,即:7-3=4;
2.顺时针拨动时针9格,即:7+9=16-12=4;
这两种方式都可以将时钟的时间校正准确,所以-3与+9是等价的。也可以说9是-3对12的补码;
即: -3=+9 (mod12)
mod12的意思是 12是模数,这个“模”表示为要丢掉的数。
我觉得可以理解为:
钟表时间只有0,1,2,3…..10,11这么多,每当在12点时可以理解为0点。
很容易联想到钟表表示方法和12进制数很相像。把这个抽象成进制概念,也是我的核心想法。
但是,计算机使用的是二进制,但是二进制的mod是多少呢?是2吗?答案肯定不是这样的!
假设计算机表示数字只占用一个字节,即为8位。我们要计算:
11-3=?
该式的二进制表示方式为:
0000 1011 - 0000 0011 = 0000 1011 + 1000 0011
计算机表示-3的方式就是符号位为1,表示负数。这个时候就用到了我们的补码了,1000 0011的补码为1111 1101 ,计算方法就是1000 0011的反码加1;那么11-3的值就是:
0000 1011 + 1111 1101=0000 1000
大家仔细观察,在这两个数相加的时候,会有进位,直到最左边第8位,再向上进位已经没有位数了,所以丢失了。这个是后的“丢失”就和mod的“模”的丢失是一样的,那么这个时候我们可以知道二进制的模为2的8次方,256!虽然是倒推给推算出来的,但是对于我理解补码、反码这一块会有很大帮助。
上式11-3就可以表示为11加上-3对256的补码来表示,根据钟表的例子,很容易求出补码为256-3=253,也就是说在计算机中:11-3=11+253,换算成8位的二进制数就是:
0000 1011 + 1111 1101=0000 1000
没错,253的二进制数,刚好就是1111 1101!其实我还发现,二进制的模并不是256,而是需要根据表示数字的内存大小来算的!一个字节8位的内存,其模大小就是2的8次方!两个字节就是2的16次方!
虽然小弟我现在刚开始看计算机原理这一块,得到的结论不一定是对的,但是我觉得这么去理解补码更直观!也能说明一部分计算机问题!
路漫漫其修远兮,吾将上下而求索!
——————————–分割线—————————————–
烦扰了我两天的问题,想了好久才想出来以上的解释。没想到只要再把《计算机组成原理》往后读一个章节就能有答案了,虽然是自己想出来的,印象比较深刻一些。但是对于自学这件事,本身就会遇到许多问题,说不定往后在读一读看一看就有了答案~以此来警示自己不怎么科学的学习方法~