位运算小结

位操作基础

位运算符
  1. Java还有一个无符号右移运算符>>>,强行右移,左侧补零。以及还有相应的复合运算符。
  2. 位操作只能用于整形数据,对 float 和 double 类型进行位操作会被编译器报错。
  3. 注意位运算的优先级较低,比+-*/还要低,记得加括号。

位运算应用

交换两个数

主要用到异或运算的性质,异或还有其他用途。
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);
    }
}

求绝对值

  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);
    }
}
  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);
    }
}

leetcodeBIT相关题目bit manipulation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 高级运算符 文档地址 作为 基本运算符 的补充,Swift 提供了几个高级运算符执行对数传值进行更加复杂的操作。这...
    hrscy阅读 4,318评论 0 2
  • 1 关键字 1.1 关键字的概述 Java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或...
    哈哈哎呦喂阅读 3,984评论 0 0
  • [学习信息的存储(编码)和处理有什么用?] 研究数字在计算机中是如何存储的,以及值的范围和算术属性,有助于我们跨越...
    唐鱼的学习探索阅读 8,566评论 4 11
  • 不斷調整狀態。求主恩惠,賜下像祢給軒軒的那種早睡早起的特異功能。 恢復工作的狀態比想像中艱難,感謝主讓我至少拿到了...
    NCNeverland阅读 669评论 0 0
  • 前台和后台乱码的问题可以说是家常便饭,一般两端定义好使用同一个字符集是不会有问题,但是昨天遇见一个小坑,分享一下。...
    夜夜丶阅读 9,272评论 0 0

友情链接更多精彩内容