概述:鉴于对2进制的知识点一直存在模糊,这里特意写一篇文章分析自己所了解的有关2进制的知识。以加深理解。
一切数据在计算机的中存储形式最后都可以归结为2进制数据,
一、运算
1.1表现形式:
2进制是形如:1101的数据,由0和1组合而成,逢2进1 。
例如9的2进制是: 1001
7的2进制是: 111
1.2算数运算 :
计算机中的算数运算底层都是2进制的运算。
例如9+7:
1001
+ 111
----------------
10000
而10000的10进制就是16。
同样9*7:
1001
x 111
-----------------1001
1001
+ 1001
---------------------
111111
而111111的10进制数就是63.
1.3位运算:
1.3.1 按位与运算:运算符“&”,运算法则:两个数据对应位都是1,则结果是1,否则为0.如果两个数的精度不同,结果与高精度数相同。
*注:根据上篇文章中的数据运算时类型转换规则:byte、short、char型数据进行混合运算时,结果会自动转换为int型。位运算也包括在内。
举例:下面为两个int型数按位与运算的过程。
00101011 10010101 11000011 01011100
10010101 00101101 10101000 11110110
-------------------------------------------------------------
00000001 00000101 10000000 01010100
1.3.2 按位或运算:运算符为“|”,运算法则:两个数据对应为都是1,则结果是0,否则为1.
举例:下面是按位或运算的过程:
00101011 10010101 11000011 01011100
10010101 00101101 10101000 11110110
-------------------------------------------------------------
10111111 10111101 11101011 11111110
1.3.3 按位异或运算:运算符为"^",运算法则:两个数对应位的二进制相同(都为0或都为1)是,结果为0,否则为1.
举例:下面是两个数按位异或的过程:
00101011 10010101 11000011 01011100
10010101 00101101 10101000 11110110
-------------------------------------------------------------10111110 10111000 01101000 10101010
1.3.4 按位取反:运算符"~",运算法则:将被操作数的二进制中1改为0,0改为1.
举例:下面是对一个数进行按位取反的过程:
00101011 10010101 11000011 01011100
--------------------------------------------------------------
11010100 01101010 00111100 10100011
1.3.5 位移操作:
<<::左移,将一个数的二进制向左移动指定位数,右边空的位置补0,移动前后二进制形式整体长度不变
>>:右移,将一个数的二进制向右移动指定位数,如果原数据最高位是0,则左空位补0,最高位是1是左空位补1.
>>>:无符号右移,将一个数的二进制向右移动指定位数,左边空位补0.*注:byte、short、char型数据位移操作后都会自动转换成int数据。
举例:下面对byte b=-84;进行>>右移1位,得到结果-42。
10101100|
________|
右移后补1-> 11010110|0 <-右移后的0被去掉
下面对b进行>>>无符号右移1位,得到结果为86.
10101100|
________|
右移后补0-> 01010110|0 <-右移后的0被去掉
由上例可以看出,对一个负数进行无符号右移操作后会得到一个正数。同时位移操作可以实现整数除以或乘以2的n次方的效果。例如,a<<2与a*4结果相同,a>>3与a/8结果相同。
总之一个数左移n位,就是将这个数乘以2的n次方。一个数右移,就是将这个数除以2的n次方。
而且位移操作相对于算术运算中的乘除更加简便,所以效率更高。
二、2进制的负数表现形式
这里以byte数据为例。
假如不考虑正负号的问题,2进制数与10进制数对应关系应该为:
00000000 0
00000001 1
00000010 2
00000011 3
:
01111110 126
01111111 127
10000000 128
10000001 129
:
11111110 254
11111111 255
当数据根据首位决定正负之后(首位为0为正数,首位为1为负数),2进制数与10进制数对应关系应该为:
00000000 0
00000001 1
00000010 2
00000011 3
:
01111110 126
01111111 127
10000000 -128
10000001 -127
:
11111110 -2
11111111 -1
将上面数进行从小到大排列:
10000000 -128
10000001 -127
:
11111011 -5
11111100 -4
11111101 -3
11111110 -2
11111111 -1
00000000 0
00000001 1
00000010 2
00000011 3
00000100 4
:
01111110 126
01111111 127
根据上面的数列总结发现:一个数a按位取反之后正好变成-(a+1),如~3=-4由此可得:~a=-(a+1)
~a=-a-1
-a=~a+1
可以看到一个数的相反数等这个数取反后加一。
三,数据越界问题
同样以bytei型数据为例。
根据上面数列我们知道byte 型数据的取值范围是-128至127;
当一个byte型数据进行运算后如果超出这个范围会发生什么情况呢?
例如:byte b=127;
b++;
System.out.prinltn(b);
结果显示为-128.这里我们可以用2进制进行解释。
127的二进制表示形式为 01111111
当其自增之后二进制变为10000000,这正好是-128的二进制形式。
例2:byte a=-1;
a++;
System.out.prinltn(a);
结果显示为0,分析:
-1的二进制表现形式:1111 1111,
如果不考虑位数的限制,其自增后的值应该为1 0000 0000;
但是因为byte型数据只有8位,所以从低到高,超出8位的数据都被舍弃了,所以实际结果是:0000 0000,也就是0的二进制形式。