众所周知,计算机底层存储数据都是用二进制表示的。包括一些数据运算也是用二进制进行运算的。
计算机在存储、运算的时候所用的二进制数,其实就是我们常说的补码。那什么是补码,还有和补码相关的原码反码又是什么?
原码,反码,补码的关系
计算机中,各种数据类型都可以用二进制来表示,因为转换的的规则不同,这里就简单的以int类型的数和二进制互相转化为例,
介绍一下原码反码和补码。
-
原码
学过十进制数和二进制数的互相转化,我们就知道在Java中,int类型的数**3**的二进制是0b0000_..._0011, 中间省略24个0。其中二进制的第一位是这个数的符号位,0代表正数,1代表负数。这种我们经常接触的二进制就是3这个数的原码。 一个数的原码就是符号位加上这个数的值, 即用第一位表示符号, 其余位表示值。 [+3]原码 = 0b0000_..._0011; [-3]原码 = 0b1000_..._0011;
-
反码
正数的反码和原码相同 [+3]反码 = 0b0000_..._0011; 负数的反码等于原码所有代表值的位取反,符号位不变 [-3]反码 = 0b1111_..._1100;
-
补码
正数的补码和原码相同 [+3]补码 = 0b0000_..._0011; 负数的补码等于负数的反码值加1 [-3]补码 = 0b1111_..._1101;
前面提到过计算机中进行数据存储和位运算都是用补码进行的,知道了一个数原码反码补码的关系,我们就可以推算出这个数的进行位运算时是怎么做的,例如~8。
取反运算符是位运算符,首先得到[8]补 = 0b0000_…1000;
再对每一位二进制数取反,得到结果的补码~8 = 0b1111…0111;
二进制数0b1111…0111的符号位是1,代表是负数,根据负数的原码反码补码的关系,我们推出原码是0b1000…_1001 = -9;