溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java中的位運算符

發(fā)布時間:2020-07-29 14:13:33 來源:網(wǎng)絡(luò) 閱讀:359 作者:51CTO朱晏辰 欄目:編程語言

Java中的位運算符

文本關(guān)鍵字:位運算符、位邏輯運算符、移位運算符

一、位運算符

大家在接觸運算符的時候通常都已經(jīng)學(xué)完了變量的使用,對于算術(shù)以及賦值運算的感覺就是So easy!這不就是小學(xué)的知識嘛,對于邏輯運算符的部分依然無壓力,這不就是中學(xué)的知識嘛?但是突然出現(xiàn)了一個位運算符,啥是移位?啥是異或?接下來就先從簡單的開始。
說起位運算符,其實就是基于數(shù)據(jù)存儲的二進制位進行的運算,更底層,所以效率更高。另外一個需要注意的問題就是:由于小數(shù)在進行存儲的時候采用的是IEEE(符號、指數(shù)、尾數(shù))方式,并不止對整數(shù)和小數(shù)部分直接轉(zhuǎn)換為二進制來存儲的,所以小數(shù)是不能使用位運算符來操作的。對于整數(shù)和字符型的運算符操作也有一些潛在的法則,相信看完這篇文章你很容易就會掌握。

二、邏輯運算

在邏輯運算中我們已經(jīng)使用過能夠表達邏輯意義的運算符,如:&&,||,!。這些運算符都有一個共同點,那就是:運算符兩邊都是布爾值或布爾表達式,他們能夠操作的數(shù)據(jù)類型有限,只能夠幫我們進行邏輯運算。有些教材將&,|等位運算符也歸為邏輯運算符,因為按位與(&)、按位或(|)能夠操作的數(shù)據(jù)類型較多,其中就包括布爾類型,并且也能夠幫助我們進行邏輯運算,但是小編還是建議按照符號本身的運算方式和操作數(shù)據(jù)類型等來記憶。

1. 與(&)

  • 與運算

與運算相當(dāng)于物理電路中的串聯(lián)電路,我們假設(shè)用1代表通路,用0代表斷路,那么對于串聯(lián)電路來說,只有當(dāng)運算符兩邊全為1(通路)時,運算結(jié)果才為1(通路)。
Java中的位運算符
Java中的位運算符

  • 按位與

那么按位與就是將運算符兩邊的數(shù)字轉(zhuǎn)換為二進制后,在每兩個對應(yīng)位置上的數(shù)字進行與運算,再將最后的結(jié)果按十進制寫出就可以了。
24 & -30:
00000000 00000000 00000000 00011010 = 26
11111111 11111111 11111111 11100010 = -30
00000000 00000000 00000000 00000010 = 26 & -30 = 2

  • 邏輯與的短路問題

當(dāng)我們在使用邏輯與(&&)時會遇到一個短路問題:當(dāng)用&&把多個布爾表達式連接起來的時候,為了以最快的速度得出結(jié)果,那么有些式子將不會執(zhí)行,被跳過的式子中的代碼也就不會被執(zhí)行。比如:(假式 && 真式 && 真式),經(jīng)過前兩個式子的結(jié)果已經(jīng)能夠確定整個式子的結(jié)果:為假,第三個式子無論為真或假都不會影響最終結(jié)果,這個時候就會進行跳過。
但是對于&(按位與),由于本質(zhì)上是一個位運算,只不過同時也支持布爾類型的直接運算而已,所以不會出現(xiàn)表達式不執(zhí)行的情況。

2. 或(|)

  • 或運算

或運算相當(dāng)于物理電路中的并聯(lián)電路,我們假設(shè)用1代表通路,用0代表斷路,那么對于并聯(lián)電路來說,只要運算符兩邊有一個為1(通路)時,運算結(jié)果就為1(通路)。
Java中的位運算符
Java中的位運算符

  • 按位或

那么按位或就是將運算符兩邊的數(shù)字轉(zhuǎn)換為二進制后,在每兩個對應(yīng)位置上的數(shù)字進行或運算,再將最后的結(jié)果按十進制寫出就可以了。
26 | -30:
00000000 00000000 00000000 00011010 = 26
11111111 11111111 11111111 11100010 = -30
11111111 11111111 11111111 11111010 = 26 | -30 = -6

  • 邏輯或的短路問題

當(dāng)我們在使用邏輯或(||)時會遇到一個短路問題:當(dāng)用||把多個布爾表達式連接起來的時候,為了以最快的速度得出結(jié)果,那么有些式子將不會執(zhí)行,被跳過的式子中的代碼也就不會被執(zhí)行。比如:(真式 || 假式 && 假式),經(jīng)過前兩個式子的結(jié)果已經(jīng)能夠確定整個式子的結(jié)果:為真,第三個式子無論為真或假都不會影響最終結(jié)果,這個時候就會進行跳過。
但是對于|(按位與),與按位或相同,是一個位運算符,不會出現(xiàn)跳過的情況。

3. 取反(~)

  • 運算規(guī)則

取反運算的規(guī)則相對簡單,同樣是在二進制位上的運算,那么遇到0變?yōu)?,遇到1變?yōu)?。
Java中的位運算符

  • 實用公式

對于一個數(shù)n的取反可以按照公式快讀得出結(jié)果:~n = -n - 1

4. 異或(^)

  • 運算規(guī)則:

其實異或的運算規(guī)則很好記,對對碰原則,兩個數(shù)相同為0,不同為1,如下表:
Java中的位運算符

  • 運算律:
    • a ^ a = 0
    • 交換律:a ^ b = b ^ a
    • 結(jié)合律:a ^ (b ^ c) = (a ^ b) ^ c
    • a ^ b ^ a = b
  • 兩數(shù)交換的用法:

如果我們需要將兩個數(shù)交換,一般都需要引入第三個變量,作為中間變量或進行運算實現(xiàn)。其實,我們還可以利用異或運算的規(guī)律來實現(xiàn):不借助第三個變量來實現(xiàn)兩個數(shù)的交換。
a = a ^ b;
b = a ^ b; -> 使用交換律:b = (a ^ b) ^ b = (b ^ a) ^ b = a
a = a ^ b; -> 此時b的值為a,a的值為:(a ^ b) -> a = (a ^ b) ^ a = b
特別注意:雖然異或可以用于兩個數(shù)的交換,但是由于異或有一個特別的性質(zhì),即a ^ a = 0,所以當(dāng)兩個數(shù)相等時,會導(dǎo)致兩個數(shù)都變?yōu)?

三、移位運算

特別注意:對于位移運算不能直接和除法的結(jié)果等同,在負(fù)數(shù)時將不相等

1. 左移(<<)

將一個整數(shù)的二進制位向左平移指定的位數(shù),由于是左移就相當(dāng)于是擴大了數(shù)值,并且每移動一位,相當(dāng)于擴大了二倍。

  • 移出的高位將被丟棄
  • 右側(cè)補零

由于正數(shù)的高位都是0,負(fù)數(shù)的高位都是1,所以在一定的范圍內(nèi),經(jīng)過向左移位不會改變數(shù)字的正負(fù)。但如果超出了一定的范圍,將會改變數(shù)字的正負(fù),并且會充滿隨機性,正負(fù)性將取決于最高位(符號位)的數(shù)值。
-7 << 2 = -28
-7 << 30 = 1073741824

2. 右移(>>)

將一個整數(shù)的二進制位向右平移指定的位數(shù),由于是右移就相當(dāng)于是縮小了數(shù)值,并且每移動一位,相當(dāng)于縮小了二倍。

  • 移出的低位將被丟棄
  • 若為正數(shù),高位補0
  • 若為負(fù)數(shù),高位補1

由于符號位在高位的部分,并且在移動的過程中的補位也是根據(jù)正負(fù)的規(guī)則在補,所以右移不會改變正負(fù)。

3. 無符號右移(>>>)

無符號右移的計算規(guī)則與右移相同,區(qū)別在于,不會進行正負(fù)的區(qū)分,高位一律用0補位。如果原數(shù)是一個負(fù)數(shù),則可能直接得到一個非常大的正數(shù)。

  • -27 >> 2 = -7
  • -27 >>> 2 = 1073741817

    四、運算規(guī)則

    1. 運算符兩邊精度不一致

  • 需要先進行精度的統(tǒng)一,即以高精度為準(zhǔn),低精度的數(shù)據(jù)進行補位
    • 正數(shù)高位補0
    • 負(fù)數(shù)高位補1

      2. 移位運算規(guī)則

  • 移動的位數(shù)不應(yīng)該超過該數(shù)字對應(yīng)的二進制位數(shù)
    • 得到的結(jié)果無數(shù)學(xué)意義
    • 會得到一些極端值結(jié)果
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI