位运算中的 AND &、OR | 、NOT ~ 、^ XOR 的使用
·
位运算中的 AND &、OR | 、NOT ~ 、^ XOR 的使用
按位与 (&)
- 口诀:同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
性质:
- 交换律:a ^ b = b ^ a
- 结合律:(a ^ b) ^ c = a ^ (b ^ c)
- 自反性:a ^ a = 0
- 与零的异或: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 + " ");
}
}
}
请注意,这里的加密和解密示例是非常简单的,在实际的加密应用中,会使用更复杂的算法和技术来确保安全性。
更多推荐
所有评论(0)