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。
但在上面的示例中,这似乎不是结果。为什么?因为整数文字是ints, 实际上意味着. 即,最左边的位为零。0b111111110b00000000000000000000000011111111
许多程序员对这种右移行为感到沮丧,并希望数字始终用零填充。所以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