位运算(Bitwise-Operation)
简介(Introduction)
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。
描述(Description)
-
位运算是计算机内的一种最基本的运算方式,快捷高效。运算的逻辑是先将两个操作数转化成二进制数,然后做位运算。
位运算符 含义 & 按位“与” | 按位“或” ^ 按位“异或” ~ 取反 << 左移 >> 右移
A B ~A A | B A & B A ^ B 0 0 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1 0 1 1 0 - 对于 \(<<\) 和 \(>>\) 运算,在数据可以表达的范围内,\(a << k\) 相当于 \(a * 2^k\),而 \(a >> k\) 相当于 \(\large\frac{a}{2^k}\)
- 如果是一个
偶数 ^ 1
那么答案是偶数 + 1
,如果是一个奇数 ^ 1
,那么答案是奇数 - 1
Tips:
- 位运算的操作对象只能是整型或者字符型数据
- 操作数的位移运算不改变原数的值
代码(Code)
- 求 \(n\) 的第 \(k\) 位二进制数字
int findk(int n, int k) { return n >> k & 1; }
- 得到二进制中最后一个 \(1\)
int lowbit(int x) { // 例如:101000 则返回 1000 return x & -x; }
示例(Example)
- \(lowbit\) 函数:
-
二进制数:
-
一个整数的负数是源码的补码 —— 即二进制数 取反加一,\(-x\) 二进制表示为:
-
那么 \(x\ \& -x\) 表示为:
-
应用(Application)
二进制中 \(1\) 的个数
给定一个长度为 \(n\) 的数列,请你求出数列中每个数的二进制表示中 \(1\) 的个数。
输入格式
第一行包含整数 \(n\)。
第二行包含 \(n\) 个整数,表示整个数列。输出格式
共一行,包含n个整数,其中的第 \(i\) 个数表示数列中的第 \(i\) 个数的二进制表示中 \(1\) 的个数。
数据范围
\(1 ≤ n ≤ 100000\)
\(0 ≤ 数列中元素的值 ≤ 10^9\)
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2
- 题解:
// C++ Version #include <iostream> using namespace std; int n; int lowbit(int x) { return x & -x; } int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) { int t; cin >> t; int res = 0; while (t) t -= lowbit(t), res ++ ; cout << res << ' '; } return 0; }