CodeGym /Java Blog /Toto sisi /Java 按位運算符
John Squirrels
等級 41
San Francisco

Java 按位運算符

在 Toto sisi 群組發布
在今天的課程中,我們將熟悉 Java 位運算符並考慮如何使用它們的示例。您可能熟悉“位”這個詞。如果不是,讓我們回憶一下它的意思:) 位是計算機中最小的信息單位。它的名字來自二進制數字。一位可以用兩個數字中的一個表示:1 或 0。有一個基於 1 和 0 的特殊二進制數字系統。我們不會在這裡深入數學叢林。我們只會注意到,Java 中的任何數字都可以轉換為二進制形式。為此,您需要使用包裝器類。
按位運算符 - 1
例如,以下是如何為int執行此操作:

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
控制台輸出: 101010110 1010 10110(我加了空格方便閱讀)是十進制數342。我們實際上已經將這個數字分解為單獨的位:0 和 1。對位執行的操作稱為按位操作
  • ~ - 按位非。
這個運算符非常簡單:它傳遞數字的每一位,然後翻轉位:0 變成 1,1 變成 0。如果我們將它應用於我們的數字 342,會發生以下情況: 101010110 是表示為二進制數的 342 010101001 是表達式 ~342 的值 讓我們嘗試將其付諸實踐:

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
控制台輸出: 169 169 是我們在熟悉的十進制系統中的 結果 ( 010101001 ):)
  • & - 按位與
如您所見,它看起來與邏輯與 ( && ) 非常相似。您會記得, &&運算符僅在兩個操作數都為真時才返回真。按位&以類似的方式工作:它逐位比較兩個數字。比較產生第三個數字。例如,讓我們以數字 277 和 432 為例: 110110000 是 277 表示為二進制數 1000101011 是 432 表示為二進制數 接下來,運算符&將高位數字的第一位與低位數字的第一位進行比較。因為這是一個 AND 運算符,所以只有當兩個位都為 1 時,結果才為 1。在任何其他情況下,結果為 0。 100010101 &&運算符 首先,我們比較兩個數字的第一位,然後是第二位,然後是第三位,依此類推。正如您所看到的,只有兩種情況下數字中的對應位都等於 1(第一位和第五位)。所有其他比較都產生 0。所以最後我們得到了10001000這個數字,在十進制中,它對應的數字是272,我們來查一下:

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
控制台輸出: 272
  • | - 按位或。
該運算符的工作方式相同:逐位比較兩個數字。只有現在如果至少一位是 1,那麼結果就是 1。讓我們看一下相同的數字(277 和 432):100010101 | 110110000 _______________ 110110101 - | 的結果 運算符 這裡我們得到了不同的結果:唯一保持為零的位是那些在兩個數字中都為零的位。結果是數字 110110101。在十進制中,它對應於數字 437 讓我們檢查一下:

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
控制台輸出: 437 我們正確計算了一切!:)
  • ^ - 按位異或(異或)
我們還沒有遇到這個操作員。但這並不復雜。它類似於普通的 OR 運算符。有一個區別:如果至少有一個操作數為真,則普通 OR 返回真。但它不一定是一個:如果兩個操作數都為真,則結果為真。但僅當恰好有一個操作數為真時,異​​或才返回真。如果兩個操作數都為真,則普通 OR 返回真(“至少有一個為真”),但 XOR 返回假。這就是為什麼它被稱為異或。了解前面的按位運算符是如何工作的,您可能可以輕鬆計算出 277 ^ 432。但讓我們再一起深入研究一下 :) 100010101 ^ 110110000 _____________ 010100101 - ^ 的結果operator 這就是我們的結果。兩個數字中相同的那些位產生 0(意味著“只有一個”測試失敗)。但是形成 0-1 或 1-0 對的位變成了 1。我們的結果是數字010100101。在十進制中,它對應於數字165。讓我們看看我們的計算是否正確:

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
控制台輸出: 165 超級!一切都和我們想的一樣:) 現在是時候熟悉位移運算符了。名字足以說明問題。我們取一些數字,並將它的位向左或向右移動 :) 讓我們看看它的樣子:

左移

向左移動的位由<<指示 。這是一個示例:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
在此示例中,數字 x = 64 稱為值。這是我們要移動的值的位。我們將位向左移動(你可以通過<<運算符的方向猜到這一點) 在二進制系統中,數字 64 = 1000000 數字y = 3稱為移位距離。移位距離表示要將數字x的位向右/向左移動多少位。 在我們的示例中,我們將向左移動 3 位。要更清楚地查看轉換過程,請查看圖片。在這個例子中,我們使用int s。Int 在計算機內存中佔據 32 位。這是我們原來的數字 64 的樣子:
按位運算符 - 2
現在我們取出每一位並將它們從字面上向左移動 3 個位置:
按位運算符 - 3
看看我們得到了什麼。如您所見,我們所有的位都發生了移位,並且從範圍的邊緣添加了另外 3 個零。三,因為我們移動了 3。如果我們移動了 10,就會添加 10 個零。因此,表達式x << y表示“將數字x的位向左移動 y 位”。我們表達式的結果是1000000000的數,十進制是512。讓我們檢查:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
控制台輸出: 512 發現!理論上,這些位可以無限移動,但因為我們的數字是 int 所以我們只有 32 個二進制數字可用。其中,7個已經被64(1000000)佔用。因此,如果我們向左移動 27 個位置,我們唯一的位置將超出數據類型的範圍並丟失。只剩下零!

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
控制台輸出: 0 正如預期的那樣,那個超出了 32 個可用位並消失了。我們以一個僅由零組成的 32 位數字結束。
按位運算符 - 4
自然地,這對應於十進制中的 0。這是記住左移的一個簡單規則:對於每次左移,數字乘以 2。讓我們嘗試計算以下沒有位圖的表達式 111111111 << 3 我們需要將數字 111111111 乘以2。結果,我們得到 888888888。讓我們編寫一些代碼並檢查一下:

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
控制台輸出: 888888888

右移

此操作由>>表示。它做同樣的事情,但在另一個方向!:) 我們不會重新發明輪子。讓我們用相同的int 64試試看。

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
按位運算符 - 5
按位運算符 - 6
由於向右移動 2,我們數字中的兩個極端零移出範圍並丟失。我們得到 10000,它對應於十進制控制台輸出中的數字 16: 16 這是記住右移的一個簡單規則:每次右移除以二,捨去任何餘數。比如35 >> 2 表示我們需要將35除以2兩次,捨去餘數 35/2 = 17(捨去餘數1) 17/2 = 8(捨去餘數1) 最後,35 >> 2應該等於 8。讓我們檢查一下:

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
控制台輸出: 8

Java 中的運算符優先級

在編寫和閱讀代碼時,您經常會發現組合了多個操作的表達式。了解它們的執行順序非常重要(否則,您可能會對結果感到驚訝)因為 Java 有很多操作,每個操作都在一個特殊的表中分配了一個位置:

運算符優先級

運營商 優先級
後綴 表達式++ 表達式--
一元的 ++expr --expr +expr ~ !
乘法 * / %
添加劑 + -
轉移 << >> >>>
相關的 < > <= >=實例
平等 == !=
按位與 &
按位異或 ^
按位包含或 |
邏輯與 &&
邏輯或 ||
三元的 :
任務 = += -= *= /= %= &= ^= |= <<= >>= >>>=
考慮到它們的優先級,所有操作都是從左到右執行的。例如,如果我們寫

int x  = 6 - 4/2;
然後除法運算(4/2)將首先執行。雖然它排在第二位,但它的優先級更高。圓括號和方括號表示最大優先級。你可能還記得在學校。例如,如果您將它們添加到表達式中

int x  = (6 - 4)/2;
然後首先執行減法,因為它被括在括號中。邏輯&&運算符的優先級相當低(見表),因此它通常排在最後。例如:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
該表達式將按如下方式執行:
  • 4/2 = 2

boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

boolean x = 4 > 3 && 144 <= 119;
接下來,執行比較運算符:
  • 4 > 3 = 真

boolean x = true && 144 <= 119;
  • 144 <= 119 = 錯誤

boolean x = true && false;
最後,AND 運算符 ( && ) 將最後執行。

boolean x = true && false;
boolean x = false;
例如,加法(+)運算符的優先級高於!=(不等於)比較運算符;因此,在表達式中

boolean x = 7 != 6+1;
將首先執行 6+1 操作,然後是 7 != 7 檢查(計算結果為 false),最後將結果(false)賦值給變量x(賦值通常在所有運算符中具有最低的優先級;參見桌子)。呸!這是一個巨大的教訓,但你做到了!如果您沒有完全理解本課程或之前課程中的某些內容,請不要擔心。我們以後會不止一次地談到這些話題。一些關於邏輯和數字運算的 CodeGym 課程。我們不會很快討論這些內容,但您現在閱讀它們並沒有什麼壞處。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION