1 判断奇数和偶数
如果不用位运算的话,那么大部分的判断奇数偶数的方式应该是下面这种:
if (a % 2 == 0)
//是偶数
else
//是奇数
如果使用位运算的话,可以提高效率:
if ((a & 1) == 0)
//是偶数
else if ((a & 1) != 0)
//是奇数
因为奇数的二进制表示的最后一位肯定是1,偶数的二进制表示的最后一位肯定是0,所以可以采用这种方式进行判断。
2 除2
做除法也可以使用位运算,普通的除法虽然效率很高,但是并没有二进制的除法效率高,因为二进制是计算机最底层的表示。
但是,位运算的除法只能表示除以2或者2的指数次方,比如除以2、4、8等。其他的不能使用该方法。
int a = 4;
a >> 1; // 等价于a = a / 2;
3 乘2
相应的,有除法就会有乘法,乘法就是在除法的基础上,做相反的操作就行。
int a = 3;
a<<1; //等价于 a = a * 2;
4 判断某数是否是2的幂
target | binary |
---|---|
2 | 10 |
4 | 100 |
8 | 1000 |
16 | 10000 |
32 | 100000 |
target-1 | binary |
---|---|
2-1 | 1 |
4-1 | 11 |
8-1 | 111 |
16-1 | 1111 |
32-1 | 11111 |
target&(target-1) | result |
---|---|
2&(2-1)->10&1 | 0 |
4&(4-1)->100&11 | 0 |
8&(8-1)->1000*111 | 0 |
16&(16-1)->10000&1111 | 0 |
32&(32-1)->100000&11111 | 0 |
public boolean isExponential3(int target){
return (target & (target - 1))==0 ?true: false;
}
5 计算无符号数中位1的个数
原自Leetcode中的一道题目,191. 位1的个数,题目如下:
编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例 1:输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。示例 2:
输入:00000000000000000000000010000000 输出:1 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。
示例 3:
输入:11111111111111111111111111111101 输出:31 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。
提示:
请注意,在某些语言(如
Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。进阶: 如果多次调用这个函数,你将如何优化你的算法?
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/number-of-1-bits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
5.1 思路
一个无符号数(n
)的二进制与n-1
的二进制相与,总是能消除一个1
。以n=15
为例:
n=15 | n&(n-1) | n=n&(n-1) |
---|---|---|
1111 | 1111&1110 | 111 |
111 | 111&110 | 110 |
110 | 110&100 | 100 |
100 | 100&0 | 0 |
可以看到,n
每次与n-1
相与之后,n
的二进制表示中的1
的个数总是能严格少1
。
所以,Java代码如下:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int s = 0;
if (n == 0)
return s;
while (n != 0) {
s++;
n &= (n - 1);
}
return s;
}
}
TO BE CONTINUED…