前不久做的一个笔记本BIOS相关的项目,操作对BOIS文件里面的内容时进行较多的位运算,于是顺手整理了一份位运算相关的内容。
Java 定义的位运算(bitwise operators
)直接对整数类型的位进行操作,这些整数类型包括long,int,short,char,and byte 。
所有的整数类型(除了char 类型之外)都是有符号的整数。这意味着他们既能表示正数,又能表示负数。Java 使用采用补码来表示负数。
为什么采用补码吗?这是考虑到零的交叉(zero crossing )问题。
原码:
将最高位作为符号位(以0代表正,1代表负),其余各位代表数值本身的绝对值(以二进制表示)。这个时候有一个问题:表示0的时候正0和负0表示并不一
样,所以在计算机中没有采用原码的表示形式。
反码:
一个数如果为正,则它的反码与原码相同;一个数如果为负,则符号位为1,其余各位是对原码取反。问题和上面一样的。所以,计算机中也没有采用反码来表示数
字。
补码:
一个数如果为正,则它的原码、反码、补码相同;一个数如果为负,则符号位为1,其余各位是对原码取反,然后再加1。也就是通过将与其对应的正数的二进制代
码取反(即将1变成0,将0变成1),然后对其结果加1。例如,-42就是通过将42的二进制代码的各个位取反,即对00101010
取反得到11010101 ,然后再加1,得到11010110 ,即-42
。要对一个负数解码,首先对其所有的位取反,然后加1。例如-42,或11010110 取反后为00101001
,或41,然后加1,这样就得到了42。
在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为:1
00000000。进位1被丢弃。这种情况,我们叫溢出。在计算机中,假定byte 类型的值零为0000 0000,反码为1111 1111
补码为1 0000 0000,在计算-0的补码的时候因为溢出,导致-0和+0是一样的表示,所以计算机中采用补码的形式表示数字。
数的最大值和最小值:由于最高位为符号位,所以最大值和最小值时要去掉最高位。如一个byte为8位.最大值为0111 1111 ,即 (2的7次方)
-1 = 127.最小值为1000 0000,即-( 2的7次方)
=-128。char为无符号数,没有符号位,所以最小值为0,最大值为1111 1111 1111 1111 ,即(2的16次方)
-1。
移位运算符
包括:
“>> 右移,高位补符号位”;
“>>> 无符号右移,高位补0”;
“<< 左移”;
例子:
-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。
-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同。
5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同。
5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同。
-5>>>3=536870911
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111
无论正数、负数,它们的右移、左移、无符号右移 32 位都是其本身,比如
-5<<32=-5、-5>>32=-5、-5>>>32=-5。
一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111
位逻辑运算符
包括:
& 与;
| 或;
~ 非(也叫做求反);
^ 异或
“& 与”、“| 或”、“~ 非”是基本逻辑运算,由此可以演变出“与非”、“或非”、“与或非”复合逻辑运算。“^
异或”是一种特殊的逻辑运算,对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑。
例子:
5&3=1
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001
-5&3=1
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0011
5|3=7
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0111
-5|3=-5
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1011
~5=-6
0000 0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1111 1010
~-5=4
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0100
5^3=6
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0110
-5^3=-8
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1000
参考:
http://blog.csdn.net/zdmilan/archive/2005/10/30/519634.aspx