位操作基础
- Java还有一个无符号右移运算符>>>,强行右移,左侧补零。以及还有相应的复合运算符。
- 位操作只能用于整形数据,对 float 和 double 类型进行位操作会被编译器报错。
- 注意位运算的优先级较低,比+-*/还要低,记得加括号。
位运算应用
交换两个数
主要用到异或运算的性质,异或还有其他用途。
x^ y ^y=x;
x^0=x;
x^x=0;
public class Temp{
public static void main(String[] args){
int a=2,b=12;
a ^= b;
b ^= a;
a ^= b;
System.out.println("a:"+a);
System.out.println("b:"+b);
}
}
另一种交换方法
public class Temp {
public static void main(String[] args) {
int a = 2, b = 3;
a = a + b;
b = a - b;
a = a - b;
System.out.println(a);
System.out.println(b);
}
}
判断奇偶性
奇数二进制最后一位是1,偶数为零。
public class Temp {
public static void main(String[] args) {
int a = 2, b = 3;
System.out.println("2是奇数?" + ((a & 1) == 1));
System.out.println("3是奇数?" + ((b & 1) == 1));
}
}
与2的次方相乘相除
public class Temp {
public static void main(String[] args) {
int a = 16;
System.out.println(a >> 1); // devide by 2^1
System.out.println(a << 1); // mutiple by 2^1
System.out.println(a >> 3); // devide by 2^3
}
}
判断某个数是否是2的次方
如果某个数是2的次方,则这个数的二进制形式‘1’的个数为1,即1,10,100,1000等形式。
public class Temp {
public static void main(String[] args) {
int a = 16, b = 15;
// use n&(n-1)==0&n>0
System.out.println(a > 0 && (a & (a - 1)) == 0);
System.out.println(b > 0 && (b & (b - 1)) == 0);
}
}
或者使用数学方法
public class Temp {
public static void main(String[] args) {
int a = 16, b = 15;
System.out.println((int) (Math.pow(2, 30)) % a == 0);
System.out.println((int) (Math.pow(2, 30)) % b == 0);
}
}
数学方法可以推广到3的次方,4的次方,数学定理
2^m 可以整除2^n (m>n)
变换符号
整数变负数,负数变正数,即求反再加一
public class Temp {
public static void main(String[] args) {
int a = 16, b = -15;
System.out.println(~a+1);
System.out.println(~b+1);
}
}
求绝对值
- 先移位来取符号位,int i = a >> 31; 要注意如果 a 为正数,i 等于 0,为负数,i 等于 -1。然后对i进行判断——如果i等于0,直接返回。否之,返回~a+1。
public class Temp {
public static void main(String[] args) {
int a = 16, b = -15;
System.out.println((a >> 31) == 0 ? a : ~a + 1);
System.out.println(b >> 31 == 0 ? b : ~b + 1);
}
}
- 对于任何数,与 0 异或都会保持不变,与 -1 即 0xFFFFFFFF 异或就相当于取反(注意,计算机表示使用补码表示)。因此,a 与 i 异或后再减 i(因为 i 为 0 或 -1,所以减 i即是要么加 0要么加 1)也可以得到绝对值。所以可以对上面代码优化下:
public class Temp {
public static void main(String[] args) {
int a = 16, b = -15;
int i = a >> 31;
System.out.println((a ^ i) - i);
int j = b >> 31;
System.out.println((b ^ j) - j);
}
}