1、基本概念html
全部的整數類型以二進制數字位的變化及其寬度來表示。例如,byte 型值42的二進制代碼是00101010 ,其中每一個位置在此表明2的次方,在最右邊的位以20開始。向左下一個位置將是21,或2,依次向左是22,或4,而後是8,16,32等等,依此類推。所以42在其位置1,3,5的值爲1(從右邊以0開始數);這樣42是21+23+25的和,也便是2+8+32 。java
全部的整數類型(除了char 類型以外)都是有符號的整數。這意味着他們既能表示正數,又能表示負數。Java 使用你們知道的2的補碼(two's complement )這種編碼來表示負數,也就是經過將與其對應的正數的二進制代碼取反(即將1變成0,將0變成1),而後對其結果加1。例如,-42就是經過將42的二進制代碼的各個位取反,即對00101010 取反獲得11010101 ,而後再加1,獲得11010110 ,即-42 。要對一個負數解碼,首先對其全部的位取反,而後加1。例如-42,或11010110 取反後爲00101001 ,或41,而後加1,這樣就獲得了42。編碼
若是考慮到零的交叉(zero crossing )問題,你就容易理解Java (以及其餘絕大多數語言)這樣用2的補碼的緣由。假定byte 類型的值零用00000000 表明。它的補碼是僅僅將它的每一位取反,即生成11111111 ,它表明負零。但問題是負零在整數數學中是無效的。爲了解決負零的問題,在使用2的補碼錶明負數的值時,對其值加1。即負零11111111 加1後爲100000000 。但這樣使1位太靠左而不適合返回到byte 類型的值,所以人們規定,-0和0的表示方法同樣,-1的解碼爲11111111 。儘管咱們在這個例子使用了byte 類型的值,但一樣的基本的原則也適用於全部Java 的整數類型。spa
由於Java 使用2的補碼來存儲負數,而且由於Java 中的全部整數都是有符號的,這樣應用位運算符能夠容易地達到意想不到的結果。例如,無論你如何打算,Java 用高位來表明負數。爲避免這個討厭的意外,請記住無論高位的順序如何,它決定一個整數的符號。htm
2、位邏輯運算符ci
位邏輯運算符有「與」(AND)、「或」(OR)、「異或(XOR )」、「非(NOT)」,分別用「&」、「|」、「^」、「~」表示,4-3 表顯示了每一個位邏輯運算的結果。在繼續討論以前,請記住位運算符應用於每一個運算數內的每一個單獨的位。get
表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 0it
按位非(NOT)table
按位非也叫作補,一元運算符NOT「~」是對其運算數的每一位取反。例如,數字42,它的二進制代碼爲:
00101010
通過按位非運算成爲
11010101
按位與(AND)
按位與運算符「&」,若是兩個運算數都是1,則結果爲1。其餘狀況下,結果均爲零。看下面的例子:
00101010 42 &00001111 15 00001010 10 |
按位或(OR)
按位或運算符「|」,任何一個運算數爲1,則結果爲1。以下面的例子所示:
00101010 42 | 00001111 15 00101111 47 |
按位異或(XOR)
按位異或運算符「^」,只有在兩個比較的位不一樣時其結果是 1。不然,結果是零。下面的例子顯示了「^」運算符的效果。這個例子也代表了XOR 運算符的一個有用的屬性。注意第二個運算數有數字1的位,42對應二進制代碼的對應位是如何被轉換的。第二個運算數有數字0的位,第一個運算數對應位的數字不變。當對某些類型進行位運算時,你將會看到這個屬性的用處。
00101010 42 ^ 00001111 15 00100101 37 |
位邏輯運算符的應用
下面的例子說明了位邏輯運算符:
// Demonstrate the bitwise logical operators. class BitLogic { public static void main(String args[]) {String binary[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; 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; System.out.println(" a = " + binary[a]); System.out.println(" b = " + binary[b]); System.out.println(" a|b = " + binary[c]); System.out.println(" a&b = " + binary[d]); System.out.println(" a^b = " + binary[e]); System.out.println("~a&b|a&~b = " + binary[f]); System.out.println(" ~a = " + binary[g]); } |