Java 定義的位運算(bitwise operators )直接對整數(shù)類型的位進行操作,這些整數(shù)類型包括long,int,short,char,and byte 。表4-2 列出了位運算:
表4.2 位運算符及其結果
運算符 結果
~ 按位非(NOT)(一元運算)
& 按位與(AND)
| 按位或(OR)
^ 按位異或(XOR)
>> 右移
>>> 右移,左邊空出的位以0填充
運算符 結果
<< 左移
&= 按位與賦值
|= 按位或賦值
^= 按位異或賦值
>>= 右移賦值
>>>= 右移賦值,左邊空出的位以0填充
<<= 左移賦值
續(xù)表
既然位運算符在整數(shù)范圍內(nèi)對位操作,因此理解這樣的操作會對一個值產(chǎn)生什么效果是重要的。具體地說,知道Java 是如何存儲整數(shù)值并且如何表示負數(shù)的是有用的。因此,在繼續(xù)討論之前,讓我們簡短概述一下這兩個話題。
所有的整數(shù)類型以二進制數(shù)字位的變化及其寬度來表示。例如,byte 型值42的二進制代碼是00101010 ,其中每個位置在此代表2的次方,在最右邊的位以20開始。向左下一個位置將是21,或2,依次向左是22,或4,然后是8,16,32等等,依此類推。因此42在其位置1,3,5的值為1(從右邊以0開始數(shù));這樣42是21+23+25的和,也即是2+8+32 。
所有的整數(shù)類型(除了char 類型之外)都是有符號的整數(shù)。這意味著他們既能表示正數(shù),又能表示負數(shù)。Java 使用大家知道的2的補碼(two’s complement )這種編碼來表示負數(shù),也就是通過將與其對應的正數(shù)的二進制代碼取反(即將1變成0,將0變成1),然后對其結果加1。例如,-42就是通過將42的二進制代碼的各個位取反,即對00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要對一個負數(shù)解碼,首先對其所有的位取反,然后加1。例如-42,或11010110 取反后為00101001 ,或41,然后加1,這樣就得到了42。
如果考慮到零的交叉(zero crossing )問題,你就容易理解Java (以及其他絕大多數(shù)語言)這樣用2的補碼的原因。假定byte 類型的值零用00000000 代表。它的補碼是僅僅將它的每一位取反,即生成11111111 ,它代表負零。但問題是負零在整數(shù)數(shù)學中是無效的。為了解決負零的問題,在使用2的補碼代表負數(shù)的值時,對其值加1。即負零11111111 加1后為100000000 。但這樣使1位太靠左而不適合返回到byte 類型的值,因此人們規(guī)定,-0和0的表示方法一樣,-1的解碼為11111111 。盡管我們在這個例子使用了byte 類型的值,但同樣的基本的原則也適用于所有Java 的整數(shù)類型。
因為Java 使用2的補碼來存儲負數(shù),并且因為Java 中的所有整數(shù)都是有符號的,這樣應用位運算符可以容易地達到意想不到的結果。例如,不管你如何打算,Java 用高位來代表負數(shù)。為避免這個討厭的意外,請記住不管高位的順序如何,它決定一個整數(shù)的符號。
4.2.1 位邏輯運算符
位邏輯運算符有“與”(AND)、“或”(OR)、“異或(XOR )”、“非(NOT)”,分別用“&”、“|”、“^”、“~”表示,4-3 表顯示了每個位邏輯運算的結果。在繼續(xù)討論之前,請記住位運算符應用于每個運算數(shù)內(nèi)的每個單獨的位。
表4-3 位邏輯運算符的結果
A 0 1 0 1 B 0 0 1 1 A | B 0 1 1 1 A & B 0 0 0 1 A ^ B 0 1 1 0 ~A 1 0 1 0
按位非(NOT)
按位非也叫做補,一元運算符NOT“~”是對其運算數(shù)的每一位取反。例如,數(shù)字42,它的二進制代碼為:
00101010
經(jīng)過按位非運算成為
11010101
按位與(AND)
按位與運算符“&”,如果兩個運算數(shù)都是1,則結果為1。其他情況下,結果均為零。看下面的例子:
00101010 42 &00001111 15
00001010 10
按位或(OR)
按位或運算符“|”,任何一個運算數(shù)為1,則結果為1。如下面的例子所示:
00101010 42 | 00001111 15
00101111 47
按位異或(XOR)
按位異或運算符“^”,只有在兩個比較的位不同時其結果是 1。否則,結果是零。下面的例子顯示了“^”運算符的效果。這個例子也表明了XOR 運算符的一個有用的屬性。注意第二個運算數(shù)有數(shù)字1的位,42對應二進制代碼的對應位是如何被轉換的。第二個運算數(shù)有數(shù)字0的位,第一個運算數(shù)對應位的數(shù)字不變。當對某些類型進行位運算時,你將會看到這個屬性的用處。
00101010 42 ^ 00001111 15
00100101 37
位邏輯運算符的應用
下面的例子說明了位邏輯運算符:
// Demonstrate the bitwise logical operators.
class BitLogic {
public static void main(String args[]) {
表4.2 位運算符及其結果
運算符 結果
~ 按位非(NOT)(一元運算)
& 按位與(AND)
| 按位或(OR)
^ 按位異或(XOR)
>> 右移
>>> 右移,左邊空出的位以0填充
運算符 結果
<< 左移
&= 按位與賦值
|= 按位或賦值
^= 按位異或賦值
>>= 右移賦值
>>>= 右移賦值,左邊空出的位以0填充
<<= 左移賦值
續(xù)表
既然位運算符在整數(shù)范圍內(nèi)對位操作,因此理解這樣的操作會對一個值產(chǎn)生什么效果是重要的。具體地說,知道Java 是如何存儲整數(shù)值并且如何表示負數(shù)的是有用的。因此,在繼續(xù)討論之前,讓我們簡短概述一下這兩個話題。
所有的整數(shù)類型以二進制數(shù)字位的變化及其寬度來表示。例如,byte 型值42的二進制代碼是00101010 ,其中每個位置在此代表2的次方,在最右邊的位以20開始。向左下一個位置將是21,或2,依次向左是22,或4,然后是8,16,32等等,依此類推。因此42在其位置1,3,5的值為1(從右邊以0開始數(shù));這樣42是21+23+25的和,也即是2+8+32 。
所有的整數(shù)類型(除了char 類型之外)都是有符號的整數(shù)。這意味著他們既能表示正數(shù),又能表示負數(shù)。Java 使用大家知道的2的補碼(two’s complement )這種編碼來表示負數(shù),也就是通過將與其對應的正數(shù)的二進制代碼取反(即將1變成0,將0變成1),然后對其結果加1。例如,-42就是通過將42的二進制代碼的各個位取反,即對00101010 取反得到11010101 ,然后再加1,得到11010110 ,即-42 。要對一個負數(shù)解碼,首先對其所有的位取反,然后加1。例如-42,或11010110 取反后為00101001 ,或41,然后加1,這樣就得到了42。
如果考慮到零的交叉(zero crossing )問題,你就容易理解Java (以及其他絕大多數(shù)語言)這樣用2的補碼的原因。假定byte 類型的值零用00000000 代表。它的補碼是僅僅將它的每一位取反,即生成11111111 ,它代表負零。但問題是負零在整數(shù)數(shù)學中是無效的。為了解決負零的問題,在使用2的補碼代表負數(shù)的值時,對其值加1。即負零11111111 加1后為100000000 。但這樣使1位太靠左而不適合返回到byte 類型的值,因此人們規(guī)定,-0和0的表示方法一樣,-1的解碼為11111111 。盡管我們在這個例子使用了byte 類型的值,但同樣的基本的原則也適用于所有Java 的整數(shù)類型。
因為Java 使用2的補碼來存儲負數(shù),并且因為Java 中的所有整數(shù)都是有符號的,這樣應用位運算符可以容易地達到意想不到的結果。例如,不管你如何打算,Java 用高位來代表負數(shù)。為避免這個討厭的意外,請記住不管高位的順序如何,它決定一個整數(shù)的符號。
4.2.1 位邏輯運算符
位邏輯運算符有“與”(AND)、“或”(OR)、“異或(XOR )”、“非(NOT)”,分別用“&”、“|”、“^”、“~”表示,4-3 表顯示了每個位邏輯運算的結果。在繼續(xù)討論之前,請記住位運算符應用于每個運算數(shù)內(nèi)的每個單獨的位。
表4-3 位邏輯運算符的結果
A 0 1 0 1 B 0 0 1 1 A | B 0 1 1 1 A & B 0 0 0 1 A ^ B 0 1 1 0 ~A 1 0 1 0
按位非(NOT)
按位非也叫做補,一元運算符NOT“~”是對其運算數(shù)的每一位取反。例如,數(shù)字42,它的二進制代碼為:
00101010
經(jīng)過按位非運算成為
11010101
按位與(AND)
按位與運算符“&”,如果兩個運算數(shù)都是1,則結果為1。其他情況下,結果均為零。看下面的例子:
00101010 42 &00001111 15
00001010 10
按位或(OR)
按位或運算符“|”,任何一個運算數(shù)為1,則結果為1。如下面的例子所示:
00101010 42 | 00001111 15
00101111 47
按位異或(XOR)
按位異或運算符“^”,只有在兩個比較的位不同時其結果是 1。否則,結果是零。下面的例子顯示了“^”運算符的效果。這個例子也表明了XOR 運算符的一個有用的屬性。注意第二個運算數(shù)有數(shù)字1的位,42對應二進制代碼的對應位是如何被轉換的。第二個運算數(shù)有數(shù)字0的位,第一個運算數(shù)對應位的數(shù)字不變。當對某些類型進行位運算時,你將會看到這個屬性的用處。
00101010 42 ^ 00001111 15
00100101 37
位邏輯運算符的應用
下面的例子說明了位邏輯運算符:
// Demonstrate the bitwise logical operators.
class BitLogic {
public static void main(String args[]) {