Java 中整數的位元級表示
1. 概述
Java 將數字以二進位形式儲存在記憶體中。了解整數如何在位元層級表示可以幫助我們進行某些操作。
在本教程中,我們將了解 Java 中數字表示的一些細節,並了解 Java 的位元運算是如何運作的。
2.Java中的位元運算
在Java中,整數使用32位元表示,長整數使用64位元表示。需要注意的是,Java 使用 2 的補碼表示負數。在這種情況下,如果第一位為 1,則假定該數字為負數。負數的計算方法是取該數,翻轉所有 1 和 0,然後加 1。
例如,在八位中,數字 6 是0b00000110
。要將其轉換為 -6,我們將其反轉為0b11111001
,然後加一,使其變為0b11111010.
此外,位元運算為多種用例奠定了良好的基礎,因為對於 CPU 來說,它們通常比完整的數學或邏輯表達式更快。
2.1. AND 運算子 ( &
)
AND 運算子 (&) 在兩個 32 位元整數之間執行位元 AND 運算:
int result = 0b1100 & 0b0111;
assertEquals(0b0100, result);
此操作獨立地評估每個位的位置。若操作數中對應的位元均為 1,則結果在該位置為 1;否則,將為 0。在提供的範例中:
- 12 的二進位表示 (0b1100)
- 7 (0b0111) 的二進位表示
- 位元與運算產生 0b0100
- 結果是十進制值 4
2.2.或運算符 (|)
OR 運算子 ( |
) 將兩個數字的相同位置位元進行位元 OR 運算:
int result = 0b1100 | 0b0111;
assertEquals(0b1111, result);
與 AND 運算子類似,OR 運算子比較每個位元的位置。如果操作數中至少有一個對應位元為 1,則結果在該位置將為 1。在此範例中,結果為 0b1111,相當於十進位值 15。
2.3.異或運算符 (^)
我們可以在位元異或運算中使用異或運算子 ( ^
),其中對應的位元相互運算:
int result = 0b1100 ^ 0b0111;
assertEquals(0b1011, result);
如果操作數中的對應位元不同,則此操作將結果位元設為 1。在提供的範例中,結果為 0b1011,對應於十進制值 11。
2.4.按位非 (~)
以位元非運算子 ( ~
) 反轉其運算元的位,將 1 變成 0,反之亦然:
int result = ~0b0101;
assertEquals(-0b0110, result);
每個位元都會反轉,將 0 轉換為 1,反之亦然。此外,結果是-0b0110
,相當於使用二進位補碼表示的十進制值-6
。
2.5.左移 ( <<
) 和右移 ( >>
)
左移 ( <<
) 運算子將數字的位元向左移動指定的位置數:
int result = 0b0101 << 2;
assertEquals(0b10100, result);
在這裡,我們對變數a
中儲存的值執行位元左移操作。此外,此操作將兩個位置的二進位表示向左移動,以零填充右側空出的位置。
類似地,右移 ( >>
) 運算子將位元向右移動:
int result = 0b0101 >> 1;
assertEquals(0b10, result);
相反,我們透過將變數 a 的二進位表示向右移動a
來執行位元右移操作。左側空出的位置根據有符號整數的符號位元來填滿。所以正數保持正數,負數保持負數。
3.用例:使用位元運算進行顏色修改
在這個實際範例中,我們將探討如何應用位元運算來修改 RGB 值的顏色。
3.1.原始顏色和蒙版
int originalColor = 0xFF336699;
int alphaMask = 0xFF000000;
int redMask = 0x00FF0000;
int greenMask = 0x0000FF00;
int blueMask = 0x000000FF;
在這裡,我們將原始顏色初始化為0xFF336699
,即 RGB 顏色的十六進位表示形式。此外,還定義了四個遮罩( alphaMask
、 redMask
、 greenMask
和blueMask
)來根據其位元位置擷取各個顏色分量。
3.2.提取顏色成分
int alpha = (originalColor & alphaMask) >>> 24;
int red = (originalColor & redMask) >>> 16;
int green = (originalColor & greenMask) >>> 8;
int blue = originalColor & blueMask;
我們使用位元與運算及其各自的遮罩來提取alpha
、 red
、 green
和blue
分量。然後,我們應用右移 ( >>>
) 將擷取的位元對齊到最低有效位元 (LSB) 位置。
- 由 (
originalColor
&alphaMask
) >>> 24 提取的 alpha 分量,結果為二進位 1111 1111 - 由 (
originalColor
&redMask
) >>> 16 擷取的紅色分量,二進位為 0011 0011 - 由 (
originalColor
&greenMask
) >>> 8 提取的綠色分量,二進位為 0110 1001 - 由
originalColor
和blueMask
提取的藍色分量,二進位為 1001 1001
3.3.修改顏色組件
red = Math.min(255, red + 50);
green = Math.min(255, green + 30);
接下來,我們修改red
和green
分量,模擬顏色調整。此外,我們在執行修改時確保值不超過最大值 255。
- 使用 red =
Math.min(255, red + 50)
修改紅色分量,得到二進位的 0100 0010 - 使用 green =
Math.min(255, green + 30)
修改綠色分量,得到二進位的 0111 1111
3.4.重新建立修改後的顏色
int modifiedColor = (alpha << 24) | (red << 16) | (green << 8) | blue;
此外,我們使用位元 OR (|) 和左移 (<<) 運算組合修改後的 alpha、紅色、綠色和藍色分量,以重新建立修改後的顏色。
重建的顏色計算如下: modifiedColor = (alpha << 24) | (red << 16) | (green << 8) | blue
,結果為二進位 1111 1111 0010 0010 1101 0110 1001。
4。結論
在本文中,我們了解了 Java 如何在記憶體中表示數字。我們研究了二進位表示以及如何使用它來理解位元運算。
最後,我們研究了掩碼和位移位在實際範例中的用途。
與往常一樣,本文的完整程式碼範例可以在 GitHub 上找到。