两数交换
下面展示代码。
void swap(int &a, int &b) { a ^= b ^= a ^= b; }
取绝对值
下面代码展示
int Abs(int n) {
return (n ^ (n >> 31)) - (n >> 31);
// 首先可以提出 (n >> 31),这是取 n 的最高位符号,
// 正数为0,负数为1.
// 如果为正数,那么 最后返回 n
// 如果为负数,那么 最后(n >> 31) 是补码形式的-1
// 举例 8 位 :1111 1111
// ^ 上 全 1 的 32 位数, 结果将把 n 转化为 反码,
// 最后 - -1 等于 反码 + 1 等于补码。
// 补码 = 原码 取反 + 1
}
取最大小值
下面展示代码MAX/MIN
。
int max(int a, int b) { return b & ((a - b) >> 31) | a & (~(a - b) >> 31); }
int min(int a, int b) { return a & ((a - b) >> 31) | b & (~(a - b) >> 31); }
// 两个数相减与 0 比较, 在对数比较里面比较常见,
// 这里 a > b, (a - b >> 31)(- 比 >> 运算级高)为 0
// ~后为全 1 32位数。
汉明权重
下面展示代码。
// 求 x 的汉明权重
// 求 x 的汉明权重
int popcount(int x) {
int cnt = 0;
while (x) {
cnt++;
x -= x & -x;
}
return cnt;
}
// 这里依然是运用到了 补码,现在你该知道补码在计算机当中有多么的重要了吧。
// x & -x, 其实就是将 原来的 x 最低为(lowbit)找出来,减去
// 直到将 x 为 1 的位全部归零,循环结束
// 最终 结果 用 cnt 记录。