位运算符总结

目录

计算机中的计算都是以二进制来进行运算的,因此相比在代码中直接使用(+、-、*、/)运算符,合理使用位运算符能提高代码的执行效率。

符号 描述 运算规则
& 两个位都为1时,结果才为1
| 两个位都为0时,结果才为0
^ 异或 两个位相同为0,相异为1
~ 取反 1变0,0变1
<< 左移 各二进制全部左移若干位,高位丢弃,低位补0
>> 右移 各二进制全部右移若干位,对无符号数,高位补0,有符号数,有的编译器补符号位,有的补0

位与用途:

  • 清零:若想将一个单元清零,只要与一个各位都为0的数值相与,结果就为零。
  • 取一个数的指定数位:比如取数X=10101110的低四位,只需要另找一个数Y,令Y的低四位为1,其余位为0,即00001111,Y与X相与的结果就是X的低四位(X & Y = 00001110)。
  • 判断奇偶:只要根据最末位判断是0还是1就可以判断,是0就是偶数,是1就是奇数。
if( ( a & 1 ) == 0 )//如果a是偶数
代替
if( a % 2 == 0 )
来判断a是不是偶数

位或用途:

  • 常用来对一个数据的某些位设置为1:若要将一个数X=10101100的低四位设置为1,那么令Y=00001111,X与Y相或的结果就是将X的低四位设置为1(X | Y = 10101111) 。

异或用途:

  • 反转指定位:若要将X=10101110的低四位进行反转,令Y的低四位为1,即Y=00001111,然后将X与Y相异或即可得到(X ^ Y = 10100001)。
  • 与0相异或值不变:10101110 ^ 00000000 = 10101110
  • 交换两个数:一个数和另一个数异或两次得到还是原来的数
//不使用临时变量交换两个数
void Swap ( int &a, int &b ) {
    if ( a != b) {
        a = a ^ b;
        b = a ^ b;//a与b异或两次了,现在值为a
        a = a ^ b;//用原来的a、b表示的话,这句代码的意思是a^b^a
    }
}

取反用途:

  • 使一个属的最低位为零:使a的最低位为0,可以写成:a& ~1

不同长度的数据进行位运算:
系统会将二者按右段对齐,然后进行位运算。


移位和位运算相关的算法

一、判断奇偶

【略】

二、输出该整数的二进制中1的个数

看了一篇博文中的解法,自己写了个例子证明解法是对的,但是不好理解。先记下来,回头看看能不能再看懂了。
更新:明白了n&(n-1)的作用就是将整数n的最后一位为1的位变为0
“问题思路就是先从高位开始计算1的个数,然后把高位去掉,再计算剩余的,这里用与操作符,同1做&运算,最后剩下的是1。n&(n-1)的操作,能把n的最高位的1给去掉,以此来计数。”

public static int countOne(int num) {
    int count = 0;
    while(num != 0) {
        num &= (num - 1);
        count++;
    }
    return count;
}
三、输出该整数的二进制中0的个数
四、判断一个整数是否是2的N次幂

2的N次幂的特征:就是1的N次左移。
二进制数就是一个1右侧全是0,该数减一就是011111...1,n&(n-1)的结果应该为0。

public static boolean is2Power( int num ) {
    if(num <= 0) return false;
    return (num & (num - 1) ) == 0 ? true : false ;
}

拓展
如何判断n是不是4的幂
第一步:4的幂首先是2的幂,所以可以先判断是否为2的幂。
第二步:唯一不同的是,4的幂的二进制表示中,1全在奇数上。十六进制表示的0x55555555换成二进制表示,其奇数位上全是1,因此可以拿来与n相与,若结果为1,则是4的幂,反之不是。

如何判断n是不是3的幂
3的幂的特点,如果一个整数n是3的幂,那么其所有约数都是3的幂。

五、输出一个整数的二进制高位连续0的个数

有些不明白,高位的0会因为占用的空间不同而不同。long int与int高位的0很可能就是不同的。

六、输入一个正整数的大于等于它的最近的二次幂

你可能感兴趣的:(位运算符总结)