美文网首页
java位运算常用操作

java位运算常用操作

作者: 小小的coder | 来源:发表于2020-01-16 13:46 被阅读0次
java中常用的7个位运算符:

& 同为1则为1 否则为0
| 一位为1 则返回1
~ 将操作数的每位取反
^ 两位相同时返回0,不同时返回1
<< 左移运算符 将操作数的二进制码整体左移指定位数,右边空出的以0填充 正数---乘2^n
>> 右移运算符 将操作数的二进制码整体右移指定位数,左边空出的以符号位填充(如果是正数,就是以0填充。如果是负数,就是以1填充。) 正数---除2^n
>>>无符号右移运算符 将操作数的二进制码整体右移指定位数,左边空出来的位总是以0填充。 正数---除2^n

说明:位运算的效率高于乘除运算,因为计算机底层就是0 1二进制来处理的。

位运算优先级

~的优先级最高,其次是<<、>>和>>>,再次是&,然后是^,优先级最低的是|。

位运算总的来说比较简单,但是应用却是很多,要能熟练掌握并使用常用的应用。

位运算基础操作

//对于任意整数 a 和 b,以下表达式的结果均成立

a|0 == a;
a&-1 == a;
a&0 == 0;

a^a == 0;
a^0 == a;

a|~a == -1;
a&~a == 0;
a&a == a;
a|a == a;

a|(a&b) == a;
a&(a|b) == a;
应用一:判断奇偶数
a&1 == 0;则a为偶数
a&1 == 1;则a为奇数

说明: 1的二进制表示形式除了最后一位其余所有的位都是0,所以a&1对应的除了最后一位全部是0,我们知道,一个数如果是偶数,则最后一位二进制位肯定是0,因为其他位都是2的整数次方,而如果一个数是奇数,则最后一位二进制位肯定是1。所以,当a&1 == 0时,说明a是偶数,当a&1 == 1时,说明a是奇数。

应用二:交换两数
int a = 5;
int b = 9;
a ^= b;
b ^= a;
a ^= b;

说明:直接看第二步,其实就是这样:b = b^ (a^b) = a;

因为异或运算满足交换律,一个数亦或自己结果为0,而任意一个数亦或0都等于自身,所以b = b^ (a^ b) = b^ b^ a = 0^a = a。

再来看第三步,a = a^ b;此时,a = (a^ b)^a;(第一个a为原来的a,值为5;第二个a代表的是第二步运算,其实是交换后的b的值,这里的b也是指的是为交换之前的b),所以,a = b;(b为交换之前的b),所以两数就会发生交换。

应用三:求整数的绝对值

int i = a>>31;
System.out.println(i == 0? a : (~a + 1));

说明:对于一个整数a,a>>31,若a为正数,a>>31的值为0,若a为负数,a>>31的值为-1。当 i 的值为0时,也就是当a为正数的时候,直接就输出a本身;当 i 的值为-1时,说明a为负数,输出负数的反码 + 1,也就是这个数的绝对值。

应用四:变换符号

int a = 45;
int b = -9;
System.out.println(~a + 1);
System.out.println(~b + 1);
输出结果为-45 9,即变换了正负号。

应用五:求两个数的平均值

两个数相加有时候可能相加之后的值超出了对应类型的范围,当然可以采用大数进行处理,但是还有一种方法可以处理,

(x&y)+((x^y)>>1);
如下

package com.demo;

public class WeiYunSuan {
    public static void main(String[] args){
        System.out.println(Integer.valueOf("11111111111111110010110",2));
        System.out.println(Integer.valueOf("11111111111111010001111",2));
        System.out.println((8388502 + 8388239)/2);
        int a = 8388502; //a对应的十进制
        int b = 8388239; //b对应的十进制
        System.out.println((a&b) + (a^b)>>1);
        System.out.println(Integer.valueOf("11111111111111100010010",2));

    }
    // a   11111111111111110010110
    // b   11111111111111010001111
    // a&b 11111111111111 01000 0110
    // a^b 00000000000000 100011001
    // a^b>>1 1000 1100
    // a&b + a^b>>1  11111111111111
    // 010000110
    //  10001100
    // 11111111111111100010010
}

执行结果:

     8388502
     8388239
     8388370
     4194255
     8388370

说明了可以采用这种方法进行两个数平均值的求解

应用六:取余运算

对于 a%b,当b为2的n次方的时候 a%b等价于a&(b-1)

应用七:取int型变量的第k位

a>>(k-1)&1;运算顺序为先右移k-1位,在与1

应用八:从x位到y位共有多少个1
package com.demo;

public class WeiYunSuan {
    public static void main(String[] args){
        int a = 23;
        int sum = 0;
        System.out.println(new Integer(a).toBinaryString(a));
        for(int i = 1; i <= 4; i++)
            sum += a>>(i-1)&1;
        System.out.println(sum);
    }
}

结果:

 10111
 3
应用九:取末k位

a&((1<<k) - 1),当结果长度不够时,应该在最左端加上相应的0就可以了

总结
功能                示例         位运算
去掉最后一位    (101101->10110) x >> 1
在最后加一个0    (101101->1011010)   x < < 1
在最后加一个1    (101101->1011011)   x < < 1+1
把最后一位变成1    (101100->101101)    x | 1
把最后一位变成0    (101101->101100)    x | 1-1
最后一位取反    (101101->101100)    x ^ 1
把右数第k位变成1    (101001->101101,k=3)    x | (1 < < (k-1))
把右数第k位变成0    (101101->101001,k=3)    x & ~ (1 < < (k-1))
右数第k位取反    (101001->101101,k=3)    x ^ (1 < < (k-1))
取末三位    (1101101->101)  x & 7
取末k位    (1101101->1101,k=5) x & ((1 < < k)-1)
取右数第k位    (1101101->1,k=4)    x >> (k-1) & 1
把末k位变成1    (101001->101111,k=4)    x | (1 < < k-1)
末k位取反    (101001->100110,k=4)    x ^ (1 < < k-1)
把右边连续的1变成0    (100101111->100100000)  x & (x+1)
把右起第一个0变成1    (100101111->100111111)  x | (x+1)
把右边连续的0变成1    (11011000->11011111)    x | (x-1)
取右边连续的1    (100101111->1111)   (x ^ (x+1)) >> 1
去掉右起第一个1的左边    (100101000->1000)   x & (x ^ (x-1))
判断奇数        (x&1)==1 
判断偶数        (x&1)==0(类似x%2)
清零最低位的1      x&(x-1)
得到最低位的1      x&-x

摘录原文地址:https://jcoffeezph.top/%E4%BD%8D%E8%BF%90%E7%AE%97%E5%8F%8A%E5%85%B6%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C.html

链接2:https://juejin.im/post/5cd4c1db518825357f3203e2

相关文章

  • java位运算常用操作

    java中常用的7个位运算符: & 同为1则为1 否则为0| 一位为1 则返回1~ 将操作数的每位取反^ 两位相同...

  • java 算法题 - 面试中常见的位操作算法题

    前言 上一篇博客 聊一聊 Android 中巧妙的位操作 中,我们讲解了 java 中常用的位运算及常用应用场景,...

  • 位运算及其编程妙用

    Bitwise Operators 介绍 位操作符通常用来对操作数进行位级的操作运算。首先将运算符转换为位级,然后...

  • 位运算符

    位运算符就是用来操作二进制的位的,java提供了几种操作位的运算。位运算只能用于整型类型,char或者double...

  • 笔记

    Java中常用的计算方法 Java异或运算总结 异或运算的性质: 异或运算是基于二进制的位运算,采用符号XO...

  • 1.22(运算符)

    一 Java的算术运算符Java 中常用的算术运算符: 其中,++ 和 -- 既可以出现在操作数的左边,也可以出现...

  • 位运算

    各种位运算的使用 === 1. and运算 === and运算通常用于二进制取位操作,例如一个数 and 1的结果...

  • 算法整理(1) 位运算相关

    运算符 位运算符用来对二进制位进行操作,Java中提供了如下的位运算符:位运算符中,除 ~ 以外,其余均为二元运算...

  • 位运算

    参考:位运算技巧 位运算的使用 1.and运算and运算通常用于二进制取位操作,例如一个数and1的结果就是取二进...

  • 位运算小结

    位操作基础 Java还有一个无符号右移运算符>>>,强行右移,左侧补零。以及还有相应的复合运算符。 位操作只能用于...

网友评论

      本文标题:java位运算常用操作

      本文链接:https://www.haomeiwen.com/subject/luyfzctx.html