int a = 3; // 0 + 2 + 1 or 0011 in binary int b = 6; // 4 + 2 + 0 or 0110 in binary int c = a | b; int d = a & b; int e = a ^ b; int f = (~a & b) | (a & ~b); int g = ~a & 0x0f;
} } 在本例中,變量a與b對應位的組合代表了二進制數所有的 4 種組合模式:0-0,0-1,1-0 ,和1-1 。“|”運算符和“&”運算符分別對變量a與b各個對應位的運算得到了變量c和變量d的值。對變量e和f的賦值說明了“^”運算符的功能。字符串數組binary 代表了0到15 對應的二進制的值。在本例中,數組各元素的排列順序顯示了變量對應值的二進制代碼。數組之所以這樣構造是因為變量的值n對應的二進制代碼可以被正確的存儲在數組對應元素binary[n] 中。例如變量a的值為3,則它的二進制代碼對應地存儲在數組元素binary[3] 中。~a的值與數字0x0f (對應二進制為0000 1111 )進行按位與運算的目的是減小~a的值,保證變量g的結果小于16。因此該程序的運行結果可以用數組binary 對應的元素來表示。該程序的輸出如下: a = 0011 b = 0110 a|b = 0111 a&b = 0010 a^b = 0101 ~a&b|a&~b = 0101 ~a = 1100 4.2.2 左移運算符 左移運算符<<使指定值的所有位都左移規定的次數。它的通用格式如下所示: value << num 這里,num 指定要移位值value 移動的位數。也就是,左移運算符<<使指定值的所有位都左移num位。每左移一個位,高階位都被移出(并且丟棄),并用0填充右邊。這意味著當左移的運算數是int 類型時,每移動1位它的第31位就要被移出并且丟棄;當左移的運算數是long 類型時,每移動1位它的第63位就要被移出并且丟棄。 在對byte 和short類型的值進行移位運算時,你必須小心。因為你知道Java 在對表達式求值時,將自動把這些類型擴大為 int 型,而且,表達式的值也是int 型。對byte 和short類型的值進行移位運算的結果是int 型,而且如果左移不超過31位,原來對應各位的值也不會丟棄。但是,如果你對一個負的byte 或者short類型的值進行移位運算,它被擴大為int 型后,它的符號也被擴展。這樣,整數值結果的高位就會被1填充。因此,為了得到正確的結果,你就要舍棄得到結果的高位。這樣做的最簡單辦法是將結果轉換為byte 型。下面的程序說明了這一點: // Left shifting a byte value. class ByteShift {
public static void main(String args[]) { byte a = 64, b; int i;
i = a << 2; b = (byte) (a << 2);
System.out.println("Original value of a: " + a); System.out.println("i and b: " + i + " " + b); } }
該程序產生的輸出下所示:
Original value of a: 64 i and b: 256 0
因變量a在賦值表達式中,故被擴大為int 型,64(0100 0000 )被左移兩次生成值256 (10000 0000 )被賦給變量i。然而,經過左移后,變量b中惟一的1被移出,低位全部成了0,因此b的值也變成了0。 既然每次左移都可以使原來的操作數翻倍,程序員們經常使用這個辦法來進行快速的2 的乘法。但是你要小心,如果你將1移進高階位(31或63位),那么該值將變為負值。下面的程序說明了這一點: // Left shifting as a quick way to multiply by 2. class MultByTwo {
public static void main(String args[]) { int i; int num = 0xFFFFFFE;
for(i=0; i<4; i++) { num = num << 1; System.out.println(num);