java位运算

134 阅读3分钟

java位运算

前言在刷csp算法题,发现有题涉及位运算,所以在此记录一遍笔记。 (文章结尾附上个人的实验代码)

常见的位运算

  1. 按位异或 ^: 右对其,相同的位取0,不同位取1

  2. 按位与 &: 见假即假

  3. 按位或 |: 见真即真

  4. 左位移 <<:符号位不变,低位补0

  5. 右位移 >> :正数,高位补0,负数:高位补1

  6. 按位非 ~

  7. 无符号右位移 >>>:不区分符号位,不管正负都在高位补0

    (具体用法见文章结尾的源码)

关于位运算的二级结论:

  1. 法则一:任何数左移(右移)32的倍数位等于该数本身。
  2. 法则二:在位移运算m<<n的计算中,若n为正数,则实际移动的位数为n%32,若n为负数,则实际移动的位数为(32+n%32),右移,同理。 左移是乘以2的幂,对应着右移则是除以2的幂。m*Math.pow(2,n))相当于 m<<n。
  3. 任何数异或1就相当于按位取反。
  4. 任何数异或0等于它本身。
  5. 可以通过位运算右移31位取得符号位。

小应用:

  1. 不使用临时变量交换两个数
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));
  1. 判断奇偶

     public static boolean isOdd(int a) {
            return (a & 1) == 1;
        }
    
  2. 求绝对值

 public static Integer getAbsoluteVal(Integer a){
      /*
       * 数的绝对值等于它本身,负数的绝对值等于 按位取反再减1
       * 任何数和0异或等于它本身,任何数和1异或等于该数按位取反
       * 可以把一个数右移31位获得该数的符号位
       * */
        return (a^(a>>31)) - (a>>31);
    }
  1. 判断两个数是否是异号(直接将两个数异或然后判断最高的符号位(正负))
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));
    }
}

参考文献 blog.csdn.net/qq_42265220…