文章目录
位运算,这一计算机科学中的低层操作,常被认为是高级编程中的秘密武器。它们以极其高效的方式处理数据,尤其在需要进行大量计算或优化程序性能时,尤为重要。在本文中,我们将深入探讨位运算的基本操作及其一些高级应用,展示它们如何提升编程效率和性能。
基本位运算操作
首先,让我们从基本的位运算操作开始。这些操作包括位与(&)、位或(|)、位异或(^)和位非(~)。它们直接在二进制位上进行操作,速度极快。
位与(&
):对两个操作数的每一位进行逻辑与运算。例如,5 & 3 结果是 1,因为 0101 & 0011 等于 0001。
位或(|
):对两个操作数的每一位进行逻辑或运算。例如,5 | 3 结果是 7,因为 0101 | 0011 等于 0111。
位异或(^
):对两个操作数的每一位进行逻辑异或运算。当两个位不同则结果为1,否则为0。例如,5 ^ 3 结果是 6,因为 0101 ^ 0011 等于 0110。
位非(~
):对操作数的每一位进行取反运算。例如,~5 结果是 -6,因为 ~0101 等于 1010(考虑到计算机中的补码表示)。
运算符
优先级
运算律
高级操作
应用
import java.util.Arrays;
class MedianFinder {
public static void main(String[] args) {
System.out.println(Arrays.toString(swap(2, 4)));
System.out.println(multiply(2));
System.out.println(divide(2));
System.out.println(isOdd(3));
System.out.println(isEven(3));
System.out.println(change(-3));
System.out.println(change(3));
System.out.println(abs(-3));
System.out.println(abs(3));
System.out.println(mod(18, 4));
System.out.println(countBits(7));
System.out.println(updateBits(0b10000000000, 0b10101, 2, 6));
System.out.println(0b10001010100);
System.out.println(aplusb(3, 4));
}
/*************************************************************/
/**
* 例题1:更新二进制位(给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串))
*/
private static int updateBits(int n, int m, int i, int j) {
return (m << i) | n;
}
/**
* 例题2:A+B问题(给出两个整数 a 和 b , 求他们的和并以整数(int)的形式返回。不能使用 + 等数学运算符。)
* 解法:异或操作有一个别名叫不进位加法
*/
private static int aplusb(int a, int b) {
while (b != 0) {
//计算进位
int carry = a & b;
//计算不带进位的和
a = a ^ b;
b = carry << 1;
}
return a;
}
/**
* 例题3: 用 O(1) 时间检测整数 n 是否是 2 的幂次
*/
private static boolean checkPower(int a) {
return a > 0 && (a & (a - 1)) == 0;
}
/*************************************************************/
/**
* 位运算交换两个整数
*/
private static long[] swap(int a, int b) {
// a = a ^ b
a ^= b;
// b = b ^ a = b ^ (a ^ b) = a
b ^= a;
// a = a ^ b = (a ^ b) ^ a = b
a ^= b;
return new long[]{a, b};
}
/**
* 位运算实现乘法
*/
private static int multiply(int a) {
return a << 1;
}
/**
* 位运算实现除法
*/
private static int divide(int a) {
return a >> 1;
}
/**
* 位运算判断奇数
*/
private static boolean isOdd(int a) {
return (a & 1) == 1;
}
/**
* 位运算判断偶数
*/
private static boolean isEven(int a) {
return (a & 1) == 0;
}
/**
* 改变符号
*/
private static int change(int a) {
return ~a + 1;
}
/**
* 绝对值
*/
private static int abs(int a) {
return ~(a >> 31) == 0 ? change(a) : a;
}
/**
* 取余,a mod p, p = 2^k
*/
private static int mod(int a, int p) {
if (!checkPower(p)) {
System.out.println("p 不是 2 的幂");
return a;
}
return a & (p - 1);
}
/**
* 统计二进制数字中 1 的个数
*/
private static int countBits(int n) {
int count = 0;
while (n != 0) {
count += n & 1;
n >>>= 1;
}
return count;
}
}