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));
}
}
GO TO FULL VERSION