java位运算
前言在刷csp算法题,发现有题涉及位运算,所以在此记录一遍笔记。 (文章结尾附上个人的实验代码)
常见的位运算
-
按位异或 ^: 右对其,相同的位取0,不同位取1
-
按位与 &: 见假即假
-
按位或 |: 见真即真
-
左位移 <<:符号位不变,低位补0
-
右位移 >> :正数,高位补0,负数:高位补1
-
按位非 ~
-
无符号右位移 >>>:不区分符号位,不管正负都在高位补0
(具体用法见文章结尾的源码)
关于位运算的二级结论:
- 法则一:任何数左移(右移)32的倍数位等于该数本身。
- 法则二:在位移运算m<<n的计算中,若n为正数,则实际移动的位数为n%32,若n为负数,则实际移动的位数为(32+n%32),右移,同理。 左移是乘以2的幂,对应着右移则是除以2的幂。m*Math.pow(2,n))相当于 m<<n。
- 任何数异或1就相当于按位取反。
- 任何数异或0等于它本身。
- 可以通过位运算右移31位取得符号位。
小应用:
- 不使用临时变量交换两个数
int a = 1;
int b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a= " + a));
System.out.println("b= " + b));
-
判断奇偶
public static boolean isOdd(int a) { return (a & 1) == 1; } -
求绝对值
public static Integer getAbsoluteVal(Integer a){
/*
* 数的绝对值等于它本身,负数的绝对值等于 按位取反再减1
* 任何数和0异或等于它本身,任何数和1异或等于该数按位取反
* 可以把一个数右移31位获得该数的符号位
* */
return (a^(a>>31)) - (a>>31);
}
- 判断两个数是否是异号(直接将两个数异或然后判断最高的符号位(正负))
public static boolean isYiHao(int a,int b){
return (a^b) < 0;
}
关于位运算还有很多好玩的用法,本文目标是位运算的入门,位运算还有很多用法,感兴趣可以研究一下。以下是实验的源码:
import com.sun.deploy.util.SyncAccess;
import java.util.Arrays;
public class Main {
public static boolean isOdd(int a) {
return (a & 1) == 1;
}
public static Integer getAbsoluteVal(Integer a){
/*
* 数的绝对值等于它本身,负数的绝对值等于 按位取反再减1
* 任何数和0异或等于它本身,任何数和1异或等于该数按位取反
* 可以把一个数右移31位获得该数的符号位
* */
return (a^(a>>31)) - (a>>31);
}
public static void reverseArr(Integer[] arr1) {
//不使用temp交换变量
int i = 0;
int j = arr1.length-1;
while (i < j) {
arr1[i] = arr1[i] ^ arr1[j];
arr1[j] = arr1[j] ^ arr1[i];
arr1[i] = arr1[i] ^ arr1[j];
i++;
j--;
}
}
public static boolean isYiHao(int a,int b){
return (a^b) < 0;
}
public static void main(String[] args) {
int a = 14; //1110
int b = 18; //10010
System.out.println("aTo2 " + Integer.toString(a, 2));
System.out.println("bTo2 " + Integer.toString(b, 2));
//按位异或
int c = a ^ b;
System.out.println("a ^ b " + Integer.toString(c, 2));
//按位与 &
System.out.println("a & b " + Integer.toString(a & b, 2));
//按位或 |
//左位移 <<
System.out.println("a << 2 " + Integer.toString(14 << 2, 2));
//右位移 >>
System.out.println("a >> 2 " + Integer.toString(14 >> 2, 2));
//无符号右位移 >>>
int m = -5;
System.out.println("-5To2 " + Integer.toString(m, 2));
System.out.println("-5 >>> 2 " + Integer.toString(m >>> 2,2));
//没有无符号左位移 <<<
// 非 ~
System.out.println("~a " + Integer.toString(~14, 2));
//(m*Math.pow(2,n)) 相当于 m<<n
System.out.println("1*Math.pow(2,3)=" + (1 << 3));//2^3=8
System.out.println("3*Math.pow(2,3)=" + (3 << 3));//3*2^3=24
// System.out.println(8*Math.pow(2,-1));
//反转数组
Integer[] arr = {1,2,3,4,5};
reverseArr(arr);
System.out.println(Arrays.toString(arr));
int x = -5;
int y = 10;
System.out.println(getAbsoluteVal(x));
System.out.println(getAbsoluteVal(y));
System.out.println(isYiHao(x,y));
}
}