原码、反码、补码详解
注:机器使用的是补码,原码和反码只是为了求负数的补码,下面会说明为什么。
1、原码
把一个正数转化为二进制位,转换为二进制位的就是这个正数的原码。
举个栗:
假设用一个字节存储int类型的1
+1
原码:0000 0001
-1
原码:1000 0001
因为第一位是符号位, 所以8位二进制数的取值范围就是:
1111 1111 ~ 0111 1111
也就是:
-127 ~ 127
1 - 1
= 1+(-1)
= 0000 0001(原)+ 1000 0001(原)
= 10000010 很明显结果并不等于0
由上可知让符号位也参与计算, 对于减法来说, 结果是不正确的,所以有了反码。
2、反码
正数的反码是其本身,负数的反码是在其原码的基础上, 符号位(第一位表示符号,0代表正1代表负)不变,其余各个位取反.
+1
反码:00000001
-1
反码:11111110
1 - 1
= 0000 0001(原)+ 1000 0001(原)
= 0000 0001(反)+ 1111 1110(反)
= 1111 1111(反)= 1000 0000(原)= -0
反码虽然解决了加减运算的问题,但并没有解决正负零之分,所有就又有了补码。
3、补码
正数的补码还是是其本身,在反码的基础上最低位加1就是负数的补码.
+1
原码:0000 0001
反码:00000001
补码:00000001
-1
原码:1000 0001
反码:11111110
补码:11111111
1 - 1
= 0000 0001(原)+ 1000 0001(原)
= 0000 0001(补)+ 1111 1111(补)
= 0000 0000(补)
=0000 0000(原)
这样就解决了-0的问题,也正因此1000 0000(补)可以表示为-128 ,可以多存储一个数字,所以一个八位字节的范围为-128 ~ 127 。
看到这恐怕就不用我再总结为什么机器用补码了吧。
int 数据类型是32位。所以
最小值是 -2,147,483,648(-2^31)。
最大值是 2,147,483,647(2^31 - 1)。