可能很多人有这样的疑问,我们为什么要了解原码、反码、补码,它能帮助我们解决什么问题?在编写代码中有什么实际用途呢?
我是这样认为的,其一,作为计算机基础知识,我们必须有所了解。其二、这些基础知识无论是普通的编写代码,还是研究高超的算法都离不开它。
例:我们常见的位运算 按位与(&)、按位或(|)、取反(~)等等。
在代码中, 我们可能经常会碰到这样的需求,要计算一个数是偶数或奇数,一般我们这样写 n % 2 取余,如果余0则为偶,否则为奇。
我们可以利用按位与(&)很巧妙的解决这问题,而且效率会更高,因为位运算是对内存数据进行操作,不需要转换成十进制,因此它的处理速度更快。
我们来判断整数n是奇是偶,可以运用表达示 n & 1,如 n = 5, n & 1返回值1; 如n=6,n&1返回值0;因为,在二进制里面,末位为0表示偶数,为1表示奇数,效果与n % 2 取余是一样的,但比它要快。
当然,除了这个,还有非常多的用途。
好啦,我们进入正题!
------------------------------------------------------------------------------------------------------------------------------------------------
我们知道,计算机中所有数据最终都是以二进制数表示。
相信大家也学过如何将一个十进制数转换为二进制数,如果觉得换算比较麻烦,可以用系统自带的计算器辅助换算。
我们也学过字节与位,1字节=8位,通常在Asp.net、Java等高级编程语言中int类型默认以32位(4字节)表示,当然你可以显示申明以16位或64位表示。现假设有int类型数,值为9,在计算机中以二进制方式表示如下:
--8位--
0000 1001
--16位--
0000 0000 0000 1001
--32位--
0000 0000 0000 0000 0000 0000 0000 1001
--64位--
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1001
通过以上可以看出,数值9转换成二进制是0000 1001,在16位、32位或64位中它们占位比较多,所以前面补0填充。
OK,这是数值9的二进制表述,那么如果是-9,它在计算中如何表述呢?
在计算机中,负数是以其正值的补码形式表述的。这就需要我们搞清楚什么是原码、反码、补码,他们之间有什么暧昧的关系啦。
原码:一个整数,按照绝对值换算成的二进制数,称为原码。(数的绝对值:正数和零的绝对值是它本身,负数的绝对值是它的相反数。总之,一个数的绝对值是非负数。)
如:数值-9的绝对值为9,数值9的二进制是 0000 1001,这就是-9的原码。
反码:在原码基础上按位取反,产生的新二进制数称为原二进制数的反码。简单理解就是:原为1的变成0,原为0的变成1.
如:数值-9的原码是 0000 1001。把它的每一位取反后为 1111 0110
补码:反码加1为补码。(补码=反码+1; 反码=原码取反; 原码=数值绝对值的二进数数)
如:数值-9的原码是 0000 1001。把它的每一位取反后为 1111 0110,计算补码=反码+1,也就是 1111 0110 + 1 = 1111 0111
因此,数值-9在计算机中二进制表述为:1111 0111
我们再来一例:-15在计算机中如何表述:
1、原码,数值-15的绝对值15,它的二进制表述是 0000 1111
2、反码,原码基础上取反为: 1111 0000
3、补码,反码+1得补码, 1111 0001
所以-15在计算机里用二进制表述就是 1111 0001