二进制数的原码、反码、补码(详解)
·
一、原码、反码、补码产生原因
由于计算机的硬件决定,任何存储于计算机中的数据,其本质都是以二进制码存储。
根据冯·诺依曼提出的经典计算机体系结构框架,一台计算机由运算器、控制器、存储器、输入和输出设备组成。其中运算器只有加法运算器,没有减法运算器(据说一开始是有的,后来由于减法运算器硬件开销太大,被废了)。
所以计算机中没办法直接做减法的,它的减法是通过加法实现的。现实世界中所有的减法也可以当成加法的,减去一个数可以看作加上这个数的相反数,但前提是要先有负数的概念,这就是为什么不得不引入一个符号位。符号位在内存中存放的最左边一位,如果该位位0,则说明该数为正;若为1,则说明该数为负。
而且从硬件的角度上看,只有正数加负数才算减法,正数与正数相加,负数与负数相加,其实都可以通过加法器直接相加。
原码、反码、补码的产生过程就是为了解决计算机做减法和引入符号位的问题。
二、原码
原码:是最简单的机器数表示法,用最高位表示符号位,其他位存放该数的二进制的绝对值。
以带符号位的八位二进制数为例:0010,最高位为1表示这是个负数,在右数第2位有个1,即1*2^1=2,所以表示十进制数-2。
数值 | 二进制原码 | 数值 | 二进制原码 |
1 | 0001 | -1 | 1001 |
2 | 0010 | -2 | 1010 |
3 | 0011 | -3 | 1011 |
4 | 0100 | -4 | 1100 |
5 | 0101 | -5 | 1101 |
6 | 0110 | -6 | 1110 |
二、反码
原码最大的问题在于一个数加上它的负数不等于0,于是反码的设计思想就是为了解决这个问题。
既然一个负数时一个正数的相反数,干脆把一个正数的二进制按位取反来表示它的负数。
反码:正数的反码和原码一致;负数的反码就是它的原码除符号位外,按位取反。
正数 | 正数的原码(反码相同) | 负数 | 负数的原码 | 负数的反码 |
---|---|---|---|---|
1 | 0001 | -1 | 1001 | 1110 |
2 | 0010 | -2 | 1010 | 1101 |
3 | 0011 | -3 | 1011 | 1100 |
4 | 0100 | -4 | 1100 | 1011 |
5 | 0101 | -5 | 1101 | 1010 |
6 | 0110 | -6 | 1110 | 1001 |
三、补码
补码:正数的原码、反码、补码都一致;负数的补码等于反码+1。
负数的补码等于反码+1只是补码的求法,而不是补码的定义。如果有兴趣可以看到《计算机组成原理》,它会用”模“和”同余“的概念,严格的解释补码。
正数 | 正数的原码、反码、补码 | 负数 | 负数的原码 | 负数的反码 | 负数的补码 |
---|---|---|---|---|---|
1 | 0001 | -1 | 1001 | 1110 | 1111 |
2 | 0010 | -2 | 1010 | 1101 | 1110 |
3 | 0011 | -3 | 1011 | 1100 | 1101 |
4 | 0100 | -4 | 1100 | 1011 | 1100 |
5 | 0101 | -5 | 1101 | 1010 | 1011 |
6 | 0110 | -6 | 1110 | 1001 | 1010 |
四、举个例子
求~6的值(取反)。
- 6是正数,原码、反码、补码一致,所以6的补码是0000 0110(我们模拟八位的二进制)。
- 将补码0000 0110进行”~“计算(按位取反),得到补码1111 1001。
- 再讲补码1111 1001转换为原码,先减1拿到反码,1111 1000,再取反(符号位不变)得到原码1000 0111。
- 将原码1000 0111转换成十进制,得到-7。
更多推荐
已为社区贡献2条内容
所有评论(0)