一.计算机中的二进制表示
在计算机中,所有的内容都是以2进制的形式进行表示的,10进制是满10进1,那么2进制就是满2进1(因为我们所使用的计算机是电子计算机,电平信号只有两种情况,要么是高电平,要么是低电平,也可以理解为通电或者不通电,通电代表高电平,用1表示,不通电代表低电平,用0表示),比如1+1 = 10
注:
1个bit叫做一位,8个bit为一个字节,16bit为一个字,32个bit为一个双字,64bit为一个四字,我们一般采用字节来描述数据的大小。
现在有4个bit位,最大能够表示多大的数字呢?
>最小:0000 => 0
>最大:1111 => 15
所以在计算机中,4bit所能表示的范围就是0到15。
而在JAVA中,无论是小数还是整数都是有符号的,并且首位就是我们的符号位。
那么,现在同样是4个bit位,最大能够表示多大的数字呢?
>最小1111 => (2^2+2^1+2^0) =-7
>最大0111 =>(2^2+2^1+2^0) = 7
由于第一位是符号位,所以不参与运算,那么现在,4bit所能表示的范围就是-7到7,这样表示的我们成为原码。
所以拿4bit为例,第一位是符号位(符号位是1代表这个数是负数,符号位是0代表这个数是正数),不参与运算,那么4bit的范围就是-7到7。
1.原码
虽然原码表示很简单,但是如果用原码去做加减法的时候很麻烦,还是拿4bit为例:
1+(-1) = 0001+1001,怎么让计算机去进行计算呢?虽然我们一眼就能看出来1+(-1)=0,但是计算机不知道啊。有人可能会说结果就是按位相加,满2进1,但是最后的结果确是-2,显然是不正确的!所以,为了解决这种情况,就引入了反码的概念。
2.反码
正数的反码还是他本身。
负数的反码是在符号位不变的基础上,其余各位按位取反。
经过上面的定义以后,我们再来进行1+(-1):
由于引入了反码的概念,所以1取反后还是他本身,而-1取反后,符号位不变,其余各位按位取反后就变成了1110。
所以1+(-1)=0001+1110=1111 => -0(用反码进行表示,最高位的1是符号位,其余3个1取反后是3个0,所以结果是-0)
但是,这样就会出现一个问题,1111代表-0,0000代表+0。在实数范围内,0有正负之分吗?可以同时存在+0和-0吗?那显然是不行的。
3.补码
根据上面的问题,我们引入最终的解决方案,那就是补码:
正数的补码还是其本身。
负数的补码是在其原码的基础上,符号位不变,其余各位取反后+1(即在反码的基础上+1)
其实讲到这里,仔细思考的话就已经可以发现-0已经被消除了!在这里,我们在拿1+(-1)举例:
1的补码还是等于其本身等于0001,-1的补码等于其反码+1等于1110+1=1111
所以1+(-1)=0001+1111=(1)0000=+0
所以现在,4bit所能够表示的范围就是-8到+7(JAVA使用的就是补码)