如何合理使用位运算

目录

标志位

寄存器位段操作

位运算的其他应用


标志位

我们经常都会使用到标志位的操作,来标记是否去实现某个功能。比如冒泡排序中当排序没有完成,始终将一个标志位置位(flag = 1),每次循环开始又会重新清除标志位,再进行遍历。一轮循环结束,程序根据标志位是否被置位来决定是否跳出循环。

然而,在一些比较复杂的情况需要使用到多个标记时,此时使用flag1、flag2、来表示太过于繁琐,因此可以引入位运算的操作。

我们先指定一个char类型(int8_t)的数据,它是由八个字节组成,将每个字节看成一个标志位,则一个char类型的数据可以表示八个标志位,具体操作如下:

//首先我们定义一个枚举,列举出每个操作对应的位
typedef enum{
  mode1 = 0x01,  //0000 0001
  mode2 = 0x02,  //0000 0010
  mode3 = 0x04,  //0000 0100
  mode4 = 0x08,  //0000 1000
  mode5 = 0x10,  //0001 0000
  mode6 = 0x20   //0010 0000
}mode_t;

int main()
{
   uint8_t flag = 0;  //此时没有任何标志
  //置位操作
  flag |= mode1;     //将mode1添加到flag中,此时flag的最低位置位 0000 0001
  flag |= mode4;     //将第4位置位,此时flag为 0000 1001
  //也可以这样表示:
  //flag |= (1 << 4);  //将1左移四位再相与

  //判断操作
  if(flag &= mode1) {}  //flag最低位已经置位,与mode1相与结果为真
  if(flag &= mode2) {}  //flag第二位为0,与mode2相与结果为假

  //去除某种模式
  flag &= ~mode4;   //将第四位清除
  //也可以这样表示:
  //flag &= ~(1 << 4);

}

通过以上操作,可以轻松地通过一个数据表示出需要执行哪几种工作模式,不仅方便高效还增加了可读性。

寄存器位段操作

struct u0{
  unsigned int leading :3;
  unsigned int FLAG1: 1;
  unsigned int FLAG2: 1;
  int trailing: 27;
};//冒号后面表示这个变量占用几个比特,结构体大小为以上比特之和

struct u0 uu;
uu.leading = 2; //010
uu.FLAG1 = 0;  //0
uu.FLAG2 = 1;   //1
uu.trailing = 0;
//直接通过位段操作整个寄存器

//这样表示的uu是一个32比特的数
//其二进制为
//00000000 00000000 00000000 00010010
//这样可以直接通过成员名称访问某些比特,比位运算方便

位运算的其他应用

//快速交换两个变量的值:使用异或运算符(^)可以在不使用临时变量的情况下交换两个变量的值。例如,
a ^= b; 
b ^= a; 
a ^= b; //此时a、b的值已经交换

//快速判断奇偶性:
if(x & 1 == 1) //x是奇数
if(x & 1 == 0) //x是偶数

//快速乘除以2的幂次方:对于整数 x,x << n 可以快速将 x 乘以 2 的 n 次方;x >> n 可以快速将 x 除以 2 的 n 次方(向下取整)。
  x << 3 == x * 2^3
  x >> 2 == x / 2^2

//快速判断是否为2的幂:
if(x & (x - 1) == 0) //x 是2的幂

//快速求绝对值:
(x ^ (x >> 31)) - (x >> 31)

//快速检查某位是否为1:
  if((x & (1 << n)) != 0) //检查 x 的第 n 位是否为1。

//快速设置某位为1:
    x |= (1 << n); //将 x 的第 n 位设置为1。

//快速清除某位:
  x &= ~(1 << n); //将 x 的第 n 位清零。

//快速取模:
对于整数 x 和 2 的幂次方 y,可以使用 x & (y - 1) 来取模运算 x % y,前提是 y 是2的幂。
  • 18
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值