位运算(1)-- 基础
来源:互联网 发布:时序数据库应用场景 编辑:程序博客网 时间:2024/05/29 23:44
一、基础
与:a & b
或:a | b
非:~ a
异或:a ^ b
左移:a << b
右移:a >> b
二、基本技巧
与操作:
- 指定位清零:
void clr(int& a, int i) { a &= ~(1 << i); }
- 获取指定位的值:
int get(int a, int i) { return a & (1 << i); }
- 保留某些位不变:操作数相应的要保留的位设置位1,如:
a &= 0xff
- 判断一个数是否是2的幂:
bool isPow2(int a) { return !(a & (a - 1)) && a; }
- 奇偶性判断:
a & 1
或操作:
- 设置指定位:
void set(int& a, int i) { a |= (1 << i); }
取反操作:
- 相反数:
int opposite(int a) { return ~a + 1;}
(原码和补码的相互转换)
异或操作:
- 交换两个整数:
void swap(int& a, int& b) { a ^= b ^= a ^= b; }
- 指定位取反:
void reverse(int& a, int i) { a ^= (1 << i); }
移位操作:
- 2的幂次:
a << = 2
- 循环移位:
void rol(int& a, int k) { a = a << k | a >> 32 - k; }
三、简单应用
average函数:计算两个整数
x
和y
的平均值,(x + y) / 2
可能溢出,二分法常用的x + (y - x) / 2
也可能溢出,使用位运算可避免该问题。
实现:int average = (x & y) + ((x ^ y) >> 1);
原理:回想一下半加器的原理,半加器有两部分逻辑:本位S=A⊕B (异或) 和进位C=A∙B (与)。将多位加法的本位和进位分开考虑,进位则为(x & y) << 1
(进位的结果需要加到上一位),本位则为x ^ y
,从而平均值为(x & y) + ((x ^ y) >> 1)
.abs函数:位运算避免常规方法求绝对值的分支预测
实现:int abs(int x) { int y = x >> 31; return (x + y) ^ y; }
原理:-x = ~x + 1 = ~(x - 1)
.y = x >> 31
是获得符号位。
当x >= 0
时,y = 0
, 此时(x + 0) ^ 0 = x
;
当x < 0
时,y = -1或者(0xFFFFFFFF)
,此时(x + y) ^ y
就变为(x - 1) ^ 0xFFFFFFFF(这一步异或相当于取反) = ~(x - 1) = -x
.max函数:同样避免分支预测。
实现:int max(int x, int y) { return x ^ ( (x ^ y) & (x - y) >> 31 ); }
原理:利用异或的性质,首先获得x - y
的符号位,为正符号为0否则为-1.当符号位为0时,x >= y,此时(x ^ y) & 0 = 0
,x ^ 0 = x
; 当符号位为-1时,(x ^ y) & 0xFFFFFFFF = x ^ y
,x ^ (x ^ y) = y
.常整数乘法:通过位运算对常整数的乘法进行优化。
如:计算x = x * K
将常整数K的二进制表示表达为一组 0 和 1 交替的序列:
[(0…0)(1…1)(0…0)(1…1)…]
考虑一组从位置 n 到 m 的连续 1 (n >= m),可以用以下两种形式将乘法变为位运算:
A:(x << n) + (x << n - 1) + ... + (x << m )
B:(x << n + 1) - (x << m)
- 位运算(1)-- 基础
- Pascal位运算基础(1)
- 位运算(1)
- 位运算(1)
- C语言位运算详解(基础)
- 位运算(基础篇)
- 位运算基础:入门
- java 位运算基础
- 位运算符基础
- Java基础: 位运算 << >> >>>
- 基础位运算。
- Java基础 位运算
- 位运算基础
- Java基础应用之运算符(位运算加密)
- C#基础系列(1)-- 第一部分 基础数据类型与操作 -- 位运算(1)
- PHP之位运算(入门基础,面试题目基础)
- Java学习基础:运算符和表达式(算数运算、关系运算、逻辑运算、位运算、条件运算、赋值运算)
- 位运算总结(1)
- LeetCode进阶之路( Jump Game II)
- GOF之策略模式
- C/C++静态库链接原理
- listview列表显示系统应用实例代码
- android:ToolBar和SearchView的使用总结
- 位运算(1)-- 基础
- codeforces 706B B. Interesting drink (二分)
- English Short Preface
- 经典题算法笔记:求最大子数组和
- 扑克牌大小
- java基础之集合
- LeetCode-2 Add Two Numbers
- 从泰勒展开到牛顿迭代
- jQuery UI dialog插件出错信息:$(this).dialog is not a function及js引入重复解决办法