JavaRush /Java Blog /Random-TW /Java中的位元運算

Java中的位元運算

在 Random-TW 群組發布
你可能對「擊敗」這個詞很熟悉。如果沒有,讓我們來了解一下:) 位元是計算機中資訊的最小測量單位。它的名字來自英文“ binary digital ”——“二進制數”。一位可以表示為兩個數字之一: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。我們實際上已將這個數字分成單獨的位元 - 零和一。透過它們,我們可以執行稱為位元的運算。
  • ~— 按下位元「非」運算子。

它的工作原理非常簡單:它遍歷數字的每一位並將其值更改為相反的值:從零到一,從一到零。如果我們將它應用到數字 342,我們會得到以下結果: 101010110 是二進位數字 342 010101001 是表達式 ~342 的結果 但由於 int 變數佔用 4 個位元組,即 32 位,實際上變數中的數字儲存為: 00000000 00000000 00000001 01010110- java 中 int 類型變數中的數字 342 11111111 11111111 11111110 10101001- java 中表達式 ~342 的結果 讓我們嘗試在實踐中這樣做:
public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(~x));
   }
}
控制台輸出:
11111111111111111111111010101001
  • &— 位元運算子“AND”

正如你所看到的,它的寫法與邏輯「AND」(&&)非常相似。&&正如您所記得的,true只有當兩個運算元都為 true 時,運算子才會傳回。按位的&工作方式類似:它逐位比較兩個數字。比較的結果是第三個數字。例如,我們以數字 277 和 432 為例: 100010101 - 二進位形式的數字 277 110110000 - 二進位形式的數字 432 接下來,運算子將&較高數字的第一位與較低數字的第一位進行比較。由於這是一個「AND」運算符,因此只有當兩個位元都等於 1 時,結果才等於 1。在所有其他情況下,結果將為 0。100010101 & 110110000 _______________ 100010000 - 工作結果& 我們先比較第一位兩個數字彼此的組合,然後是第二位,第三位,依此類推。正如您所看到的,只有在兩種情況下,數字中的兩個位都等於 1(第一位和第五位)。其他所有比較的結果都是0。因此,最終我們得到了數字100010000。在十進制中,它對應於數字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
我們計算的一切都正確!:)
  • ^- 位元異或(也稱為 XOR)
我們以前從未遇過這樣的操作員。但這並不複雜。它看起來像一個普通的“或”。區別之一:true如果至少一個操作數為真,則普通的“或”返回。但不一定是其中之一——如果兩者都存在的話true——那就是結果truetrue但僅當其中一個操作數為 true 時,異或才會回傳。如果兩個運算元都為 true,則會傳回常規「or」true(「至少有一個為 true」),但獨佔 or 將會傳回false。這就是為什麼它被稱為獨家。知道了前面位元運算的原理,你大概可以輕鬆地自己執行277^432運算了。但讓我們更能更好地再次一起弄清楚:) 100010101 ^ 110110000 _______________ 010100101 - 工作結果^ 這是我們的結果。兩個數字中相同的位元返回 0(“其中之一”公式不起作用)。但那些0-1或1-0的組合最終變成了一個整體。結果我們得到了數字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;//meaning
       int y = 3;//quantity

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
在此範例中,數字x=64稱為值。我們將要移動的是它的位子。我們將位元左移(這可以透過符號的方向來確定<<) 在二進位系統中,數字 64 = 1000000 這個數字y=3稱為數量。Quantity 回答了「數字的位元應該向右/向左移動多少位x?」的問題,在我們的範例中,我們將它們向左移動 3 位元。為了讓換檔過程更清晰,我們來看一張圖。在我們的範例中,我們使用 int 類型的數字。Int佔用32位元電腦記憶體。這就是我們原來的數字 64 的樣子: 位運算 - 2現在,從字面上來說,我們將每個位元向左移動 3 個單元: 位運算 - 3這就是我們得到的。正如您所看到的,我們所有的位元都已移位,並且從範圍之外添加了 3 個零。3 - 因為我們移動了 3。如果我們移動了 10,就會增加 10 個零。因此,該表達式的x << y意思是「將 y 個單元格的位元х向左移動」。我們的表達式的結果是數字 1000000000,在十進制中等於 512。讓我們檢查一下:
public class Main {

   public static void main(String[] args) {
       int x = 64;//meaning
       int y = 3;//quantity

       int z = (x << y);
       System.out.println(z);
   }
}
控制台輸出:

512
這是正確的!理論上,位元可以無限地移位。但由於我們有編號int,因此只有 32 個可用單元。其中,7 個已被數字 64(1,000,000)佔用。因此,例如,如果我們向左移動 27 次,我們唯一的單位將超出範圍並「覆蓋」。只剩零!
public class Main {

   public static void main(String[] args) {
       int x = 64;//meaning
       int y = 26;//quantity

       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;//meaning
       int y = 2;//quantity

       int z = (x >> y);
       System.out.println(z);
   }
}
位元運算 - 5位元運算 - 6由於右移 2,我們的數字的兩個極端零超出了範圍並被刪除。我們得到數字 10000,在十進制中對應數字 16。輸出到控制台:

16
記住右移的一個簡單規則:每個右移除以二,丟棄任何餘數。例如, 35 >> 2 這意味著我們需要將35除以2 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 --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 = true

    boolean x = true && 144 <= 119;
  • 144 <= 119 = false

    boolean x = true && false;
  • 最後,將執行最後一個運算子&&

    boolean x = true && false;

    boolean x = false;

    例如,加法運算子 ( +) 的優先權高於比較運算子!=(「不等於」);

    因此在表達式中:

    boolean x = 7 != 6+1;

    首先執行運算 6+1,然後檢查 7!=7 (false),最後將結果賦給false變數x。分配通常在所有操作中具有最低優先級 - 請查看表。

唷!我們的講座很長,但你做到了!如果您不完全理解本講座和先前講座的某些部分,請不要擔心,我們將來會多次涉及這些主題。以下是一些對您有用的連結:
  • 邏輯運算子- 關於邏輯運算的 JavaRush 講座。我們不會很快看到它們,但你現在可以閱讀它們,不會有任何傷害
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION