按位与 (&)

  • 口诀:同1则1,否则为0。
  • 解释:两个位都为1时,结果为1;否则为0。
  • 例子:
    0101 & 1100 = 0100
    

按位或 (|)

  • 口诀:有1则1,全0为0。
  • 解释:两个位中只要有一个为1,结果为1;否则为0。
  • 例子:
    0101 | 1100 = 1101
    

按位异或 (^)

  • 口诀:不同则1,相同为0。
  • 解释:两个位不同时,结果为1;相同为0。
  • 例子:
    0101 ^ 1100 = 1001
    

按位取反 (~)

  • 口诀:0变1,1变0。
  • 解释:每个位取反,0变成1,1变成0。
  • 例子:
    ~0101 = 1010
    

左移 (<<)

  • 口诀:左移添0,右补0。
  • 解释:将二进制数向左移动指定的位数,右侧补0。
  • 例子:
    0101 << 2 = 10100
    

右移 (>>)

  • 口诀:右移丢0,左补符号位。
  • 解释:将二进制数向右移动指定的位数,左侧补符号位(对于负数补1,正数补0)。
  • 例子:
    0101 >> 2 = 0001
    

无符号右移 (>>>)

  • 口诀:右移丢0,左补0。
  • 解释:将二进制数向右移动指定的位数,左侧始终补0。
  • 例子:
    0101 >>> 2 = 0001
    

实战技巧

  • 组合标志:使用按位或 (|) 组合多个标志位。
  • 检查标志:使用按位与 (&) 检查某个标志是否被设置。
  • 清除标志:使用按位与 (&) 和按位取反 (~) 清除某个标志。

例子

假设我们有两个标志位 FLAG_A 和 FLAG_B,分别表示为 0x01 和 0x02。

  • 组合标志:

    int flags = FLAG_A | FLAG_B; // 结果为 0x03
    
  • 检查标志:

    boolean isFlagASet = (flags & FLAG_A) != 0; // true
    boolean isFlagBSet = (flags & FLAG_B) != 0; // true
    
  • 清除标志:

    flags &= ~FLAG_A; // 清除 FLAG_A,结果为 0x02
    

XOR(异或)运算 - “消消乐”

XOR(异或)是一种位运算,其运算规则是:如果两个二进制位相同(都为0或都为1),则结果为0;如果两个二进制位不同(一个为0,另一个为1),则结果为1。

例如,对于两个二进制数1010和1100,它们的XOR运算结果如下:

  1010
^ 1100
------
  0110

性质:

  1. 交换律:a ^ b = b ^ a
  2. 结合律:(a ^ b) ^ c = a ^ (b ^ c)
  3. 自反性:a ^ a = 0
  4. 与零的异或:a ^ 0 = a

由于 3 4 的性质我们可以 交换两个变量的值
XOR运算在编程中有许多应用,例如:

  • 查找唯一元素:在数组中,所有元素都出现两次,只有一个元素出现一次,可以通过异或操作找到这个唯一的元素。
  • 交换两个变量的值:通过异或操作,可以在不使用额外变量的情况下交换两个变量的值。
  • 检测奇偶性:通过异或操作可以快速检测一个数的奇偶性。如果一个数的最低位是1,那么它是奇数;如果是0,那么它是偶数。
  • 翻转特定位:通过异或操作可以翻转一个数的特定位。例如,翻转第i位。
  • 加密和解密:异或操作可以用于简单的加密和解密。将明文与密钥进行异或操作可以得到密文,再次异或可以得到明文。

以下是使用Java语言实现利用XOR运算查找唯一元素、翻转特定位以及加密和解密的示例:

一、查找唯一元素

class Main {
    public static int findUniqueElement(int[] arr) {
        int result = 0;
        for (int num : arr) {
            result ^= num;
        }
        return result;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 2, 1};
        System.out.println("唯一元素为: " + findUniqueElement(arr));
    }
}

二、翻转特定位

假设要翻转整数num的第i位(从右往左,最低位为第0位)。

class Main {
    public static int flipBit(int num, int i) {
        return num ^ (1 << i);
    }

    public static void main(String[] args) {
        int num = 5; // 二进制为101
        int i = 1;
        System.out.println("翻转第 " + i + " 位后的结果: " + flipBit(num, i));
    }
}

三、加密和解密(简单示例)

class Main {
    public static byte[] encrypt(byte[] data, byte[] key) {
        byte[] encrypted = new byte[data.length];
        for (int i = 0; i < data.length; i++) {
            encrypted[i] = (byte) (data[i] ^ key[i % key.length]);
        }
        return encrypted;
    }

    public static byte[] decrypt(byte[] encrypted, byte[] key) {
        return encrypt(encrypted, key);
    }

    public static void main(String[] args) {
        byte[] data = {1, 2, 3, 4, 5};
        byte[] key = {6};
        byte[] encrypted = encrypt(data, key);
        byte[] decrypted = decrypt(encrypted, key);
        System.out.print("原始数据: ");
        for (byte b : data) {
            System.out.print(b + " ");
        }
        System.out.println();
        System.out.print("加密后数据: ");
        for (byte b : encrypted) {
            System.out.print(b + " ");
        }
        System.out.println();
        System.out.print("解密后数据: ");
        for (byte b : decrypted) {
            System.out.print(b + " ");
        }
    }
}

请注意,这里的加密和解密示例是非常简单的,在实际的加密应用中,会使用更复杂的算法和技术来确保安全性。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐