1. 按位左移
Java 也有 3 個移位運算符:如果你真的需要,你可以非常簡單地將數字的所有位向左或向右移動幾個位置。
要將數字的位向左移動,您需要按位左移運算符。它是這樣寫的:
a << b
其中a
是其位被移位的數字,b
是一個數字,表示將數字的位a
向左移動多少次。在此操作過程中,右側添加的低位為零。
例子:
例子 | 結果 |
---|---|
|
|
|
|
|
|
|
|
向左移動一位數字與將數字乘以 2 具有相同的效果。
想將數字乘以 16?16 與 2 4相同。所以你將數字向左移動 4 位
2.按位右移
位也可以右移。為此,請使用按位右移運算符。它是這樣寫的:
a >> b
其中a
是其位被移位的數字,b
是將數字的位右移的次數a
。
例子:
例子 | 結果 |
---|---|
|
|
|
|
|
|
|
|
向右移動一位數字與將數字除以 2 的效果相同。
在這個操作過程中,左邊添加的高位是零,但不總是!
有符號數的最左邊的位稱為符號位:如果數字是正數,則為0
;但如果數字為負數,則該位為1
。
將數字的位右移時,符號位的值通常也會移動,數字的符號會丟失。因此,對於負數(最左邊的位是1
),該位得到特殊處理。將一個數的位右移時,0
如果最左邊的位是 則在左邊加a 0
,1
如果最左邊的位是 則在左邊加a 1
。
但在上面的示例中,這似乎不是結果。為什麼?因為整數文字是int
s, 實際上意味著. 即,最左邊的位為零。0b11111111
0b00000000000000000000000011111111
許多程序員對這種右移行為感到沮喪,並希望數字始終用零填充。所以Java又增加了一個右移運算符。
它是這樣寫的:
a >>> b
其中a
是其位被移位的數字,b
是將數字的位右移的次數a
。此運算符始終在左側附加零,而不管 number 的符號位的原始值如何a
。
3. 使用標誌
程序員在按位和移位操作的基礎上創建了一個幾乎全新的研究領域:使用標誌。
當計算機內存很少時,將大量信息塞入一個數字非常流行。數字被視為位數組:int 是 32 位,long 是 64 位。
您可以在這樣的數字中寫入很多信息,尤其是當您需要存儲邏輯(true
或false
)值時。單個long
就像一個boolean
由 64 個元素組成的數組。這些位稱為標誌,並使用以下操作進行操作:
-
設置標誌(使特定位等於
1
) -
重置標誌(使特定位等於
0
) -
檢查標誌(檢查特定位的值)
下面是按位運算符是如何完成的。
立旗
要將特定位設置為1
,您需要在要設置其位的數字與專門創建的數字之間執行按位或運算,其中只有該位是1
。
例如,假設您有數字0b00001010
並且需要將第 5 位設置為1
。在這種情況下,您需要:
0b00001010 | 0b00010000 = 0b00011010
如果第 5 位已經設置為 1,那麼什麼都不會改變。
一般來說,設置標誌的操作可以這樣寫
a | (1 << b)
a
其位將被設置為 的數字在哪裡1
。Andb
是要設置的位的位置。在這裡使用左移運算符非常方便,因為您可以立即知道我們正在處理的是哪一位。
重置標誌
0
要在不干擾其他位的情況下重置特定&
位(即0
設置1
為對於您要重置的位。
例如,假設您有數字0b00001010
,需要將第 4 位設置為0
。在這種情況下,您需要:
0b00001010 & 0b11110111 = 0b00000010
如果第 4 位已經設置為零,那麼什麼都不會改變。
一般來說,重置一個標誌的操作可以這樣寫
a & ~(1 << b)
a
位將被重置為 的數字在哪裡0
。並且b
是要清除的位的位置。
1
為了得到一個除我們希望為零的位之外所有位都為零的數字,我們首先 向左移動 1 bNOT
個位置,然後使用按位運算符反轉結果。
檢查標誌
除了設置或重置特定標誌外,有時您只需要檢查是否設置了給定標誌,即某個位是否等於1
。使用 bitwise 很容易做到這一點&
。
1
例如,假設您需要檢查number 中的第 4 位是否設置為0b00001010
。然後你需要這樣做:
if ( (0b00001010 & 0b00001000) == 0b00001000 )
一般來說,檢查一個標誌的操作可以寫成如下
(a & (1 << b)) == (1 << b)
a
正在檢查其位的數字在哪裡。並且b
是要檢查的位的位置。
4.加密
位XOR
運算常被程序員用於簡單的加密。一般來說,這樣的加密看起來像這樣:
result = number ^ password;
number
我們要加密的數據在哪裡,password
是一個特殊的數字,作為數據的“密碼”,result
是加密後的數字。
number == (number ^ password) ^ password;
這裡重要的是,當XOR
運算符兩次應用於一個數字時,它會生成原始數字,而不管“密碼”如何。
number
要從中恢復encrypted result
,您只需要再次執行該操作:
original number = result ^ password;
例子:
class Solution
{
public static int[] encrypt(int[] data, int password)
{
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++)
result[i] = data[i] ^ password;
return result;
}
public static void main(String[] args)
{
int[] data = {1, 3, 5, 7, 9, 11};
int password = 199;
// Encrypt the array of data
int[] encrypted = encrypt(data, password);
System.out.println(Arrays.toString(encrypted));
// Decrypt the array of data
int[] decrypted = encrypt(encrypted, password);
System.out.println(Arrays.toString(decrypted));
}
}