位运算

计算机中的数在内存中都是以二进制形式进行存储的,用位运算就是直接对整数在内存中的二进制位进行操作,因此其执行效率非常高,在程序中尽量使用位运算进行操作,这会大大提高程序的性能。

位运算概览

符号 描述 运算规则
& 两个位都为1时,结果才为1
竖线 两个位都为0时,结果才为0
^ 异或 两个位相同为0,相异为1
~ 取反 0变1,1变0
<< 左移 各二进位全部左移若干位,高位丢弃,低位补0
>> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

任何数和 00 做异或运算,结果仍然是原来的数,即 a ^ 0=aa⊕0=a。
任何数和其自身做异或运算,结果是 00,即 a ^ a=0a⊕a=0。
异或运算满足交换律和结合律,即 a ^ b ^ a=b ^ a ^ a=b ^ (a ^ a)=b ^

常见位运算问题

位操作实现乘除法

数 a 向右移一位,相当于将 a 除以 2;数 a 向左移一位,相当于将 a 乘以 2

int a = 2;
a >> 1; ---> 1
a << 1; ---> 4

位操作交货两数

位操作交换两数可以不需要第三个临时变量,虽然普通操作也可以做到,但是没有其效率高

//普通操作
void swap(int &a, int &b) {
  a = a + b;
  b = a - b;
  a = a - b;
}

//位与操作
void swap(int &a, int &b) {
  a ^= b;
  b ^= a;
  a ^= b;
}

位与操作解释:第一步:a ^= b ---> a = (a^b);

第二步:b ^= a ---> b = b(ab) ---> b = (bb)a = a

第三步:a ^= b ---> a = (ab)a = (aa)b = b

位操作判断奇偶数

只要根据数的最后一位是 0 还是 1 来决定即可,为 0 就是偶数,为 1 就是奇数。

if(0 == (a & 1)) {
 //偶数
}

位操作交换符号

交换符号将正数变成负数,负数变成正数

int reversal(int a) {
  return ~a + 1;
}

整数取反加1,正好变成其对应的负数(补码表示);负数取反加一,则变为其原码,即正数

位操作进行高低位交换

给定一个 16 位的无符号整数,将其高 8 位与低 8 位进行交换,求出交换后的值,如:

34520的二进制表示:
10000110 11011000

将其高8位与低8位进行交换,得到一个新的二进制数:
11011000 10000110
其十进制为55430

从上面移位操作我们可以知道,只要将无符号数 a>>8 即可得到其高 8 位移到低 8 位,高位补 0;将 a<<8 即可将 低 8 位移到高 8 位,低 8 位补 0,然后将 a>>8 和 a<<8 进行或操作既可求得交换后的结果。

unsigned short a = 34520;
a = (a >> 8) | (a << 8);

posted @ 2020-12-29 15:35  朝明  阅读(181)  评论(0编辑  收藏  举报