1. 程式人生 > >Java 位運 算 符 【轉】

Java 位運 算 符 【轉】

1. 算術運算子
+ :加法
- :減法
* :乘法
/ :除法
% :取餘運算

2. 關係運算符
< :只能比較基本型別資料之間的關係,不能比較物件之間的關係。
> : (同關係運算符“<”)
<=: (同關係運算符“<”)
>=: (同關係運算符“<”)
== :若使用該運算子比較兩個物件的引用(變數),則實質上是比較兩個變數是否引用了相同的物件。所謂相同的物件是指,是否是在堆疊(Heap)中開闢的同一塊兒記憶體單元中存放的物件。
若比較兩個物件的引用(變數)所引用的物件的內容是否相同,則應該使用equals()方法,該方法的返回值型別是布林值。需要注意的是:若用類庫中的類建立物件,則物件的引用呼叫equals()方法比較的是物件的內容;若用自定義的類來建立物件,則物件的引用呼叫equals()方法比較的是兩個引用是否引用了同一個物件,因為第二種情況equals()方法預設的是比較引用。
!= :(同關係運算符“==”)

3. 邏輯運算子 (操作符只能是布林型別的)
&&
||
!

4. 位運算子
&
|
^
~ :不可以與=聯用,因為~是一元操作符;不可以對布林型別的資料進行按位非運算

5. 移位運算子(只能處理整數運算子)
Char、byte、short型別,在進行移位之前,都將被轉換成int型別,移位後的結果也是int型別;移位符號右邊的運算元只擷取其二進位制的後5位(目的是防止因為移位操作而超出int型別的表示範圍:2的5次方是32,int型別的最大範圍是32位);對long型別進行移位,結果仍然是long型別,移位符號右邊的操作符只擷取其二進位制的後6位。
<< :
>> :若符號位為正,則在最高位插入0;若符號位為負,則在最高位插入1
>>> :無論正負,都在最高位插入0


[size=medium]Java 位運 算 符 [/size]


位運算子用來對二進位制位進行操作 ,Java中提 供 了 如 下所 示 的 位 運 算符 :


位 運 算 符 (>>,<<,>>>,&,|,^,~ ) ,位運 算 符 中 ,除 ~ 以 外 ,其餘 均 為 二 元 運 算 符 。 操 作 數 只 能 為 整 型 和字 符 型 數 據 。


基礎知識


補碼


所有的整數型別(除了char 型別之外)都是有符號的整數。這意味著他們既能表示正數,又能表示負數。 Java使用 補 碼 來 表 示 二

進 制 數 ,在補 碼 表 示 中 ,最高 位 為 符號 位 ,正數 的 符 號 位 為 0,負數 為 1。補 碼 的 規 定 如 下 :


對 正 數 來 說 ,最高 位 為 0,其餘 各 位 代 表 數 值 本 身 (以二 進位制 表 示 ),如 +42的補碼 為 00101010。


對 負 數 而 言 ,把該 數 絕 對 值 的 補 碼 按 位 取 反 ,然後 對 整 個數 加 1,即得 該 數的 補 碼 。 如 -42的補 碼 為 11010110 (00101010 按 位 取 反 11010101 +1=11010110 )


用 補 碼 來 表 示 數 ,0的補 碼 是 唯 一 的 ,都為 00000000。 (而在 原碼 ,反碼 表 示中 ,+0和 -0的表

示 是 不 唯 一 的 ,可參 見 相 應 的 書 籍 )。而 且 可 以用 111111表示 -1的補 碼 (這也 是 補 碼 與 原 碼 和

反 碼 的 區 別 )。


型別長度


整 型


整型常 量 在 機 器 中 佔 32位 ,具有 int型的 值 ,對於 long型值 ,則要在 數 字 後 加 L或 l,如

123L表示 一 個 長 整 數 ,它在 機 器 中 佔 64位。整 型 變 量 的 類 型 有 byte、 short、 int、

long四種 。 下面 列 出各 類 型 所 在 內 存 的 位 數 和 其表 示 範 圍 。


資料型別 描述 所佔位數


Integers


byte Byte-length integer 8-bit two's complement


short Short integer 16-bit two's complement


int Integer 32-bit two's complement


long


Long integer 64-bit two's complement


Real numbers


float Single-precision floating point 32-bit IEEE 754


double Double-precision floating point 64-bit IEEE 754


Other types


char A single character 16-bit Unicode character


boolean A boolean value (true or false) true or false


int型別 是 最 常 使 用 的 一 種 整 數 類 型 。 它 所 表 示的 數 據 範 圍 足 夠 大 ,而且 適 合 於

32位、64位處 理 器 。 但 對 於 大 型 計 算 ,常會 遇 到 很 大 的 整 數 ,超出 int型別 所 表 示 的 範 圍 ,這時

要 使 用long型別 。


由 於 不 同 的 機 器 對 於 多字 節 數 據 的 存 儲 方 式 不 同 ,可能 是 從 低 字 節 向 高 字 節 存 儲 ,也


可能 是 從 高 字 節 向 低 字 節 存 儲 ,這樣 ,在分 析 網 絡 協 議 或 文 件 格 式 時 ,為了 解 決 不 同 機 器 上


的字 節 存 儲 順 序 問 題 ,用 byte型別 來 表 示 數 據 是 合 適 的 。 而 通 常 情 況 下 ,由於 其 表 示 的 數 據


範圍 很 小 ,容易 造 成 溢 出 ,應避 免 使 用 。


short類 型 則 很 少 使 用 ,它限 制 數 據 的 存 儲 為 先 高 字 節 ,後低 字 節 ,這樣 在 某 些 機 器 中 會出錯 。


整型 變 量 的 定 義 ,如 :


byte b; //指定變數b為byte型


short s; //指定變數s為short型


int i; //指定變數i為int型


long l; //指定變數l為long型


浮 點 型 (實型 )資料


實型 變 量 的 類 型 有 float和 double兩種 ,下表 列 出 這 兩 種 類 型 所 佔 內 存 的 位 數 和 其 表示 範


圍。


資料型別 所佔位數 數的範圍


float 32 3.4e-038~3.4e+038


double 64 1.7e-308~1.7e+308


雙精 度 類 型 double比單 精 度 類 型 float具有 更 高 的 精 度 和 更 大 的 表 示 範 圍 ,常常 使 用 。


(三)實型 變 量 定 義 ,如


float f; //指 定 變 量 f為 float型


double d; //指 定 變 量 d為 double型


[注 ]與 C、 C++不同 ,Java中沒 有 無 符 號 型 整 數 ,而且 明 確 規 定 了 整 型 和 浮 點 型 數 據 所 佔 的


記憶體 字 節 數 ,這樣 就 保 證 了 安 全 性 、 魯 棒 性 和 平 臺 無 關 性。


Java 位運算子


Java 定義的位運算(bitwise operators )直接對整數型別的位進行操作,這些整數型別包括long,int,hort,char,and byte 。表4-2 列出了位運算:


運算子


結果


~


按位非(NOT)(一元運算)


&


按位與(AND)


|


按位或(OR)


^


按位異或(XOR)


>>


右移


>>>


右移,左邊空出的位以0填充 ;無符號右移


>=


右移賦值


>>>=


右移賦值,左邊空出的位以0填充 ;無符號左移


>使指定值的所有位都右移規定的次數。它的通用格式如下所示:


value >> num


這裡,num 指定要移位值value 移動的位數。也就是,右移運算子>>使指定值的所有位都右移num位。下面的程式片段將值32右移2次,將結果8賦給變數a:


int a = 32;


a = a >> 2; // a now contains 8


當值中的某些位被“移出”時,這些位的值將丟棄。例如,下面的程式片段將35右移2 次,它的2個低位被移出丟棄,也將結果8賦給變數a:


int a = 35;


a = a >> 2; // a still contains 8


用二進位制表示該過程可以更清楚地看到程式的執行過程:


00100011 35


>> 2


00001000 8


將值每右移一次,就相當於將該值除以2並且捨棄了餘數。你可以利用這個特點將一個整數進行快速的2的除法。當然,你一定要確保你不會將該數原有的任何一位移出。




移時,被移走的最高位(最左邊的位)由原來最高位的數字補充。例如,如果要移走的值為負數,每一次右移都在左邊補1,如果要移走的值為正數,每一次右移都

在左邊補0,這叫做符號位擴充套件(保留符號位)(sign extension ),在進行右移操作時用來保持負數的符號。例如,–8 >>

1 是–4,用二進位制表示如下:


11111000 –8 >>1 11111100 –4


一個要注意的有趣問題是,由於符號位擴充套件(保留符號位)每次都會在高位補1,因此-1右移的結果總是–1。有時你不希望在右移時保留符號。例如,

下面的例子將一個byte

型的值轉換為用十六進位制表示。注意右移後的值與0x0f進行按位與運算,這樣可以捨棄任何的符號位擴充套件,以便得到的值可以作為定義陣列的下標,從而得到對

應陣列元素代表的十六進位制字元。


// Masking sign extension.


class HexByte {


static public void main(String args[]) {


char hex[] = {


’0’, ’1’, ’2’, ’3’, ’4’, ’5’, ’6’, ’7’,


’8’, ’9’, ’a’, ’b’, ’c’, ’d’, ’e’, ’f’’


};


byte b = (byte) 0xf1;


System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);


}


}


該程式的輸出如下:


b = 0xf1


無符號右移




如上面剛剛看到的,每一次右移,>>運算子總是自動地用它的先前最高位的內容補它的最高位。這樣做保留了原值的符號。但有時這並不是我們想要


的。例如,如果你進行移位操作的運算數不是數字值,你就不希望進行符號位擴充套件(保留符號位)。當你處理畫素值或圖形時,這種情況是相當普遍的。在這種情況

下,不管運算數的初值是什麼,你希望移位後總是在高位(最左邊)補0。這就是人們所說的無符號移動(unsigned shift

)。這時你可以使用Java 的無符號右移運算子>>> ,它總是在左邊補0。


下面的程式段說明了無符號右移運算子>>> 。在本例中,變數a被賦值為-1,用二進位制表示就是32位全是1。這個值然後被無符號右移24位,當然它忽略了符號位擴充套件,在它的左邊總是補0。這樣得到的值255被賦給變數a。


int a = -1; a = a >>> 24;


下面用二進位制形式進一步說明該操作:


11111111 11111111 11111111 11111111 int型-1的二進位制程式碼>>> 24 無符號右移24位00000000 00000000 00000000 11111111 int型255的二進位制程式碼


由 於無符號右移運算子>>>

只是對32位和64位的值有意義,所以它並不像你想象的那樣有用。因為你要記住,在表示式中過小的值總是被自動擴大為int

型。這意味著符號位擴充套件和移動總是發生在32位而不是8位或16位。這樣,對第7位以0開始的byte

型的值進行無符號移動是不可能的,因為在實際移動運算時,是對擴大後的32位值進行操作。下面的例子說明了這一點:


// Unsigned shifting a byte value.


class ByteUShift {


static public void main(String args[]) {


int b = 2;


int c = 3;


a |= 4;


b >>= 1;


c 1.

對於左移運算,每左移一個位,高階位都被移出(並且丟棄),並用0填充右邊。這意味著當左移的運算數是int

型別時,每移動1位,它的第31位就要被移出並且丟棄;當左移的運算數是long 型別時,每移動1位它的第63位就要被移出並且丟棄。


2.

左移都可以使原來的運算元翻倍,程式設計師們經常使用這個辦法來進行快速的2

的乘法。但是你要小心,如果你將1移進高階位(31或63位),那麼該值將變為負值。


3. 在對byte

和short型別的值進行移位運算時 , Java將自動把這些型別擴大為 int 型,而且,移位後的值也是int

型;如果左移不超過31位,原來對應各位的值不會丟棄。但是,如果你對一個負的byte 或者short型別的值進行移位運算,它被擴大為int

型後,它的符號也被擴充套件,結果的高位就會被1填充。因此,為了得到正確的結果,你就要捨棄得到結果的高位。這樣做的最簡單辦法是將移位運算的結果再轉換成

byte 型 。


4.

每右移一次,就相當於將該值除以2並且捨棄了餘數。你可以利用這個特點將一個整數進行快速的2的除法。當然,你

一定要確保你不會將該數原有的任何一位移出。


5. 無符號右移(>>>)與右移的區別:


(1) 每一次右移,>>運算子總是自動地用它的先前最高位的內容補它的最高位。這樣做保留了原值的符號


(2) 無符號移動總是在高位(最左邊)補0。


6. 與C、C++不同,Java中沒有無符號型整數,而且明確規定了整型和浮點型資料所佔的記憶體位元組數,這樣就保證了安全性、魯棒性和平臺無關性。


其他:


(1)BCD碼(二到十進位制編碼)


人們通常習慣使用十進位制數,而計算機內部多采用二進位制表示和處理數值資料,因此在計算機輸入和輸出資料時,就要進行由十進位制到二進位制的轉換處理。


把十進位制數的每一位分別寫成二進位制形式的編碼,稱為二進位制編碼的十進位制數,即二到十進位制編碼或BCD(Binary Coded Decimal)編碼。


BCD碼編碼方法很多,通常採用8421編碼,這種編碼方法最自然簡單。其方法使用四位二進位制數表示一位十進位制數,從左到右每一位對應的權分別是23、22、21、20,即8、4、2、1。例如十進位制數1975的8421碼可以這樣得出


1975(D)=0001 1001 0111 0101(BCD)


用四位二進位制表示一位十進位制會多出6種狀態,這些多餘狀態碼稱為BCD碼中的非法碼。BCD碼與二進位制之間的轉換不是直接進行的,當需要將BCD

碼轉換成二進位制碼時,要先將BCD碼轉換成十進位制碼,然後再轉換成二進位制碼;當需要將二進位制轉換成BCD碼時,要先將二進位制轉換成十進位制碼,然後再轉換成

BCD碼。


(2)字元編碼


在計算機中,對非數值的文字和其他符號進行處理時,首先要對其進行數字化處理,即用二進位制編碼來表示文字和符號。字元編碼就是以二進位制的數字來對

應字符集的字元,目前用得最普遍的字符集是ANSI,對應ANSI字符集的二進位制編碼就稱為ANSI碼,DOS和Windows系統都使用了ANSI碼。

在輸入過程中,系統自動將使用者輸入的各種資料按編碼的型別轉換成相應的二進位制形式存入計算機儲存單元中;在輸出過程中,再由系統自動將二進位制編碼資料轉換

成使用者可以識別的資料格式輸出給使用者。


(3)ASCⅡ碼


用七位二進位制表示字元的一種編碼,使用一個位元組表示一個特殊的字元,位元組高位為0或用於在資料傳輸時的校驗。附表為標準的ASCⅡ碼錶。