原码 反码 补码

计算机中只能做加法运算,它的减法是通过加法来实现的;

原码,反码,补码的产生过程,就是为了解决计算机做减法和引入符号位的问题。

原码

原码是最简单的机器数表示法。用最高位表示符号位,‘1’表示负号,‘0’表示正号。其他位存放该数的二进制的绝对值。
原码 反码 补码_第1张图片

0001+0010=00111+2=3)        正数之间的加法 OK
0000+1000=1000+0+-0=-0) 问题不大
0001+1001=10101+-1=-2)  正数与负数相加 NG
1010+1001=0011-2+-1=3)  负数与负数相加 NG

反码

正数的反码还是等于原码
负数的反码就是他的原码除符号位外,按位取反

原码最大的问题就在于一个数加上他的相反数不等于零!
反码的设计思想就是冲着解决这一点
原码 反码 补码_第2张图片

0001+0010=00111+2=3)          正数之间的加法 OK

正数与负数相加
0001+1110=11111+-1= -0)   OK
	 反   反
0101+1010=11115+-5= -0)   OK
	 反   反
0010+1001=10112+-6= -4)   OK
	 反   反

负数与负数相加	 
1110+1101=1011-1+-2=-4)  NG
反   反    反
1110+1101=1011-1+-2=-3) OK  但是从原码来看,他其实是-3。巧合吗?
反   反    原
											
1110+1100=1010-1+-3=-5) NG
反   反    反
1110+1100=1010-1+-3=-2) NG 验证了上面确实是巧合
反   反    原

通过原码可以得到:
正数之间的加法OK
负数加负数只是符号出错而已,数值的绝对值是对的
通过反码可以得到:
正数与负数相加 用反码就可以运算

补码

常见算法:
正数的补码等于他的原码
负数的补码等于反码+1

《计算机组成原理中》
负数的补码等于他的原码自低位向高位,尾数的第一个‘1’及其右边的‘0’保持不变,左边的各位按位取反,符号位不变。

并不是把反码+1就定义为补码。只不过是补码正好就等于反码加1罢了!!

补码的思想

原码 反码 补码_第3张图片
现在是9点,如果我想调到6点;

9 - 3 -> 6 往前拨3个小时
9 + 9 -> 6 往后拨9个小时

这里称12为模,写作mod12; 称9-312位模的补数,记作 -3+9(mod 12)

也就是说 :减去一个数和加上它的补数效果是一样的;

Why 补码 = 反码再+1 = -1再取反码

参考 为什么补码的补码就是原码?二进制里为什么减一取反和取反加一等价?

一个 N 位的二进制数,可表示的最大值是2^N-1;
假设存在 x+y = 2^N-1 --> x+y+1 = 2^N;如果此时把2^N 当做模 --> x 和 y+1 就互为补数;
       x+y = 2^N-1 --> x 和 y 除了符号位其余位都是相反的;一个为0另一个就为1 --> x 和 y 互为反码;

由 x+y+1 = 2^N --> x的补数为y+1 即 y+1 = 2^N-1-x+1 = 2^N-x ;
由 x+y = 2^N-1 --> x的反码为(2^N-1-x),(2^N-1-x)+1 其实就是 反码再+1 的由来;

对于求x的补码如果用如下算法
2^N-1-(x-1) = 2^N-x ; 发现和上面结果一样 这个步骤就是  -1再取反码 的由来;

综上 补码 = 反码再+1 =  -1再取反码 
	     -8		-1		-2		-3		-4		-5		-6		-7
负数  原码 1000	1001	1010	1011	1100	1101	1110	1111
			
负数  反码 1111	1110	1101	1100	1011	1010	1001	1000

负数绝对值 0000	0001	0010	0011	0100	0101	0110	0111

负数反码+负数绝对值
	      1111	1111   	1111	1111 	 1111	1111   	1111	1111+1
   10000    10000  	10000  	10000  	10000  	10000 	10000 	10000
正好为 Mod(16) 

所以 

反码+1 正好等于 补码

补码的实例

四位二进制数的模是多少呢?也就是说四位二进制数最大容量是多少?其实就是2^4=16

2的同余数,就等于10000-0010=11101401106-00102=01106+111014)=1010020=16+4)
对于四位二进制数,硬件决定最大只能存放4位,正好是01004111014)就是(-2)的补码;这可能也是为什么负数的符号位是‘1’而不是‘0’;

原码 反码 补码_第4张图片

在补码中也不存在负零了,因为1000表示-8

0001+0010=00111+2=3)        正数之间的加法 OK

正数与负数相加
0001+1111=00001+-1= 0)   OK
	 补
0101+1011=00005+-5= 0)   OK
	 补   
0010+1010=11002+-6= -4)  OK
	 补   补

负数与负数相加	 
1111+1110=1101-1+-2=-3)  OK
补   补    补
											
1111+1101=1100-1+-3=-4) OK
补   补    补
	0		1		2		3		4		5		6		7		8		9		10		11		12		13		14		15
原码	0000	0001	0010	0011	0100	0101	0110	0111	1000	1001	1010	1011	1100	1101	1110	1111
	0		1		2		3		4		5		6		7		-0		-1		-2		-3		-4		-5		-6		-7
																
反码	0000	0001	0010	0011	0100	0101	0110	0111	1111	1110	1101	1100	1011	1010	1001	1000
																
																
补码	0000	0001	0010	0011	0100	0101	0110	0111	10000	1111	1110	1101	1100	1011	1010	1001
	0		1		2		3		4		5		6		7		-8		-7		-6		-5		-4		-3		-2		-1

原码 反码 补码_第5张图片

算补码的小技巧

4位加法器的话,把-8为原点:-5的补码就是-8加3;

1000-8+00113= 1011(-5)

八位加法器的话,把-128当补码原点;
十六位加法器的话,把-32768当补码原点;
在这里插入图片描述

以上参考:原码,反码,补码杂谈
在这里插入图片描述

你可能感兴趣的:(基础知识,java)