1. 按位左移

Java 还有 3 个移位运算符:如果你真的需要,你可以非常简单地将数字的所有位向左或向右移动几个位置。

要将数字的位向左移动,您需要按位左移运算符。它是这样写的:

a << b

其中a是其位被移位的数字,是一个数字,表示将数字的位向左b移动多少次。a在此操作过程中,右侧添加的低位为零。

例子:

例子 结果
0b00000011 << 1
0b00000110
0b00000011 << 2
0b00001100
0b00000011 << 5
0b01100000
0b00000011 << 20
0b001100000000000000000000

向左移动一位数字与将数字乘以 2 具有相同的效果。

想将数字乘以 16?16 与 2 4相同。所以你将数字向左移动 4 位


2.按位右移

位也可以右移。为此,请使用按位右移运算符。它是这样写的:

a >> b

其中a是其位被移位的数字,b是将数字的位右移的次数a

例子:

例子 结果
0b11000011 >> 1
0b01100001
0b11000011 >> 2
0b00110000
0b11000011 >> 5
0b00000110
0b11000011 >> 20
0b00000000

向右移动一位数字与将数字除以 2 的效果相同。

在这个操作过程中,左边添加的高位是零,但并不总是

重要的!

有符号数的最左边的位称为符号位:如果数字是正数,则为0;但如果数字为负数,则此位为1

将数字的位右移时,符号位的值通常也会移动,数字的符号会丢失。因此,对于负数(最左边的位是1),该位得到特殊处理。将一个数的位右移时,0如果最左边的位是 则在左边加a 01如果最左边的位是 则在左边加a 1

但在上面的示例中,这似乎不是结果。为什么?因为整数文字是ints, 实际上意味着. 即,最左边的位为零。0b111111110b00000000000000000000000011111111

许多程序员对这种右移行为感到沮丧,并希望数字始终用零填充。所以Java又增加了一个右移运算符

它是这样写的:

a >>> b

其中a 是其位被移位的数字,b  是将数字的位右移的次数a。此运算符始终在左侧附加零,而不管 number 的符号位的原始值如何a



3. 使用标志

程序员在按位和移位操作的基础上创建了一个几乎全新的研究领域:使用标志。

当计算机内存很少时,将大量信息塞入一个数字非常流行。数字被视为位数组:int 是 32 位,long 是 64 位。

您可以在这样的数字中写入很多信息,尤其是当您需要存储逻辑(truefalse)值时。单个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));
   }
}