在今天的課程中,我們將熟悉 Java 位運算符並考慮如何使用它們的示例。您可能熟悉“位”這個詞。如果不是,讓我們回憶一下它的意思:) 位是計算機中最小的信息單位。它的名字來自
二進制數字。一位可以用兩個數字中的一個表示:1 或 0。有一個基於 1 和 0 的特殊二進制數字系統。我們不會在這裡深入數學叢林。我們只會注意到,Java 中的任何數字都可以轉換為二進制形式。為此,您需要使用包裝器類。
例如,以下是如何為
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 的樣子:
現在我們取出每一位並將它們從字面上向左移動 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 位數字結束。
自然地,這對應於十進制中的 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);
}
}
由於向右移動 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;
該表達式將按如下方式執行:
boolean x = 6 - 2 > 3 && 12*12 <= 119;
boolean x = 6 - 2 > 3 && 144 <= 119;
boolean x = 4 > 3 && 144 <= 119;
接下來,執行比較運算符:
boolean x = true && 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 課程。我們不會很快討論這些內容,但您現在閱讀它們並沒有什麼壞處。
GO TO FULL VERSION