前不久做的一個筆記本BIOS相關(guān)的項目,操作對BOIS文件里面的內(nèi)容時進行較多的位運算,于是順手整理了一份位運算相關(guān)的內(nèi)容。
Java 定義的位運算(bitwise operators )直接對整數(shù)類型的位進行操作,這些整數(shù)類型包括long,int,short,char,and byte 。
所有的整數(shù)類型(除了char 類型之外)都是有符號的整數(shù)。這意味著他們既能表示正數(shù),又能表示負數(shù)。Java 使用采用補碼來表示負數(shù)。
為什么采用補碼嗎?這是考慮到零的交叉(zero crossing )問題。
原碼:
將最高位作為符號位(以0代表正,1代表負),其余各位代表數(shù)值本身的絕對值(以二進制表示)。這個時候有一個問題:表示0的時候正0和負0表示并不一 樣,所以在計算機中沒有采用原碼的表示形式。
反碼:
一個數(shù)如果為正,則它的反碼與原碼相同;一個數(shù)如果為負,則符號位為1,其余各位是對原碼取反。問題和上面一樣的。所以,計算機中也沒有采用反碼來表示數(shù) 字。
補碼:
一個數(shù)如果為正,則它的原碼、反碼、補碼相同;一個數(shù)如果為負,則符號位為1,其余各位是對原碼取反,然后再加1。也就是通過將與其對應的正數(shù)的二進制代 碼取反(即將1變成0,將0變成1),然后對其結(jié)果加1。例如,-42就是通過將42的二進制代碼的各個位取反,即對00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要對一個負數(shù)解碼,首先對其所有的位取反,然后加1。例如-42,或11010110 取反后為00101001 ,或41,然后加1,這樣就得到了42。
在計算機中,如果我們用1個字節(jié)表示一個數(shù),一個字節(jié)有8位,超過8位就進1,在內(nèi)存中情況為:1 00000000。進位1被丟棄。這種情況,我們叫溢出。在計算機中,假定byte 類型的值零為0000 0000,反碼為1111 1111 補碼為1 0000 0000,在計算-0的補碼的時候因為溢出,導致-0和+0是一樣的表示,所以計算機中采用補碼的形式表示數(shù)字。
數(shù)的最大值和最小值:由于最高位為符號位,所以最大值和最小值時要去掉最高位。如一個byte為8位.最大值為0111 1111 ,即 (2的7次方) -1 = 127.最小值為1000 0000,即-( 2的7次方) =-128。char為無符號數(shù),沒有符號位,所以最小值為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
其結(jié)果與 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
其結(jié)果與 -5*2*2*2 完全相同。
5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其結(jié)果與 5/(2*2*2) 完全相同。
5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其結(jié)果與 5*2*2*2 完全相同。
-5>>>3=536870911
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111
無論正數(shù)、負數(shù),它們的右移、左移、無符號右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一個有趣的現(xiàn)象是,把 1 左移 31 位再右移 31 位,其結(jié)果為 -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
Java 定義的位運算(bitwise operators )直接對整數(shù)類型的位進行操作,這些整數(shù)類型包括long,int,short,char,and byte 。
所有的整數(shù)類型(除了char 類型之外)都是有符號的整數(shù)。這意味著他們既能表示正數(shù),又能表示負數(shù)。Java 使用采用補碼來表示負數(shù)。
為什么采用補碼嗎?這是考慮到零的交叉(zero crossing )問題。
原碼:
將最高位作為符號位(以0代表正,1代表負),其余各位代表數(shù)值本身的絕對值(以二進制表示)。這個時候有一個問題:表示0的時候正0和負0表示并不一 樣,所以在計算機中沒有采用原碼的表示形式。
反碼:
一個數(shù)如果為正,則它的反碼與原碼相同;一個數(shù)如果為負,則符號位為1,其余各位是對原碼取反。問題和上面一樣的。所以,計算機中也沒有采用反碼來表示數(shù) 字。
補碼:
一個數(shù)如果為正,則它的原碼、反碼、補碼相同;一個數(shù)如果為負,則符號位為1,其余各位是對原碼取反,然后再加1。也就是通過將與其對應的正數(shù)的二進制代 碼取反(即將1變成0,將0變成1),然后對其結(jié)果加1。例如,-42就是通過將42的二進制代碼的各個位取反,即對00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要對一個負數(shù)解碼,首先對其所有的位取反,然后加1。例如-42,或11010110 取反后為00101001 ,或41,然后加1,這樣就得到了42。
在計算機中,如果我們用1個字節(jié)表示一個數(shù),一個字節(jié)有8位,超過8位就進1,在內(nèi)存中情況為:1 00000000。進位1被丟棄。這種情況,我們叫溢出。在計算機中,假定byte 類型的值零為0000 0000,反碼為1111 1111 補碼為1 0000 0000,在計算-0的補碼的時候因為溢出,導致-0和+0是一樣的表示,所以計算機中采用補碼的形式表示數(shù)字。
數(shù)的最大值和最小值:由于最高位為符號位,所以最大值和最小值時要去掉最高位。如一個byte為8位.最大值為0111 1111 ,即 (2的7次方) -1 = 127.最小值為1000 0000,即-( 2的7次方) =-128。char為無符號數(shù),沒有符號位,所以最小值為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
其結(jié)果與 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
其結(jié)果與 -5*2*2*2 完全相同。
5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其結(jié)果與 5/(2*2*2) 完全相同。
5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其結(jié)果與 5*2*2*2 完全相同。
-5>>>3=536870911
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111
無論正數(shù)、負數(shù),它們的右移、左移、無符號右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。
一個有趣的現(xiàn)象是,把 1 左移 31 位再右移 31 位,其結(jié)果為 -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