c通过位运算求绝对值_15种位运算的妙用,你都知道吗?

ec87fa16f8463f3628ae3898c0d915e4.png

d388b8f1389ae39225def1d6ec28f33f.png

位运算在驱动开发中是经常遇到的,尤其是置0和置1。既要指定的位数发生变化,又不能改变其它位的值,还要高效率的编写代码,这时候技巧就很重要了。在位运算中有几个符号: | 按位或 、& 按位与 、 ^ 异或 、~按位非。

应用技巧

1

判断int型变量a是奇数还是偶数

a&1   = 0 偶数
a&1   = 1 奇数

2

取int型变量a的第k位 (k=0,1,2……sizeof(int))

a>>k&1

3

将int型变量a的第k位清0

a=a&~(1<

4

将int型变量a的第k位置1

a=a|(1<

5

int型变量循环左移k次

(设sizeof(int)=16)

a=a<>16-k   

6

int型变量a循环右移k次

(设sizeof(int)=16)

a=a>>k|a<<16-k

e40e4753f0532f6eded63d7653406ae5.png
#include <stdio.h>

int main()
{
	printf("学习从来不是一个人的事情,要有个相互监督的伙伴n");
	printf("工作需要学习C/C++或者有兴趣学习C/C++的伙伴可以家我球球
_2208165112n");

	return 0;
}

7

整数的平均值

对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:

int average(int x, int y)   //返回X,Y 的平均值
{   
     return (x&y)+((x^y)>>1);
}

8

判断一个整数是不是2的幂,对于一个数 x >= 0

boolean power2(int x)
{
    return ((x&(x-1))==0)&&(x!=0);
}

9

用位运算符交换两个整数

void swap(int x , int y)
{
    x ^= y;
    y ^= x;
    x ^= y;
}

10

计算绝对值

int abs( int x )
{
  int y ;
  y = x >> 31 ;
  return (x^y)-y ;        //or: (x+y)^y
}

11

取模运算转化成位运算 (在不产生溢出的情况下)

a % (2^n) 等价于 a & (2^n - 1)

12

乘法运算转化成位运算 (在不产生溢出的情况下)

a * (2^n) 等价于 a<< n

13

除法运算转化成位运算 (在不产生溢出的情况下)

a / (2^n) 等价于 a>> n
      例: 12/8 == 12>>3

14

判断赋值

if (x == a) x= b;
   else x= a; 等价于 x= a ^ b ^ x;

15

x 的 相反数

(~x+1)

技巧虽好,但是大家还是最好自己啃一啃才能知道味道呀,闲暇时,不防拿出来品一品,悟一悟其中的原理所在。

10675b45101d8b00d582cc0bebfac76c.png

练一练

#include
int main()
{
     unsigned int i = 0x9f43bda5;
    unsigned int ret = 0;
     printf("i %xn",i);
    //将 i 第3位置1    
     ret = i | ( 1 << 3 );
     printf("ret %xn",ret);
     //将 i 第2位置0    
     ret = i  & ~( 1 << 2 );
     printf("ret %xn",ret);
     //将 i 第4~9位置1    
     ret = i | ( 0x3f << 4 );
     printf("ret %xn",ret);    
     //将 i 第3~7位置0    
     ret = i & ~(0x1f << 3 );
     printf("ret %xn",ret);
     //将 i 第1~7和9~11位置1    
     ret = i | ( 0x3f << 1 | 7 << 9);
     printf("ret %xn",ret);
     //将 i 第2~8位置13~20位置0
     ret = i & ~( 0x7f << 2 | 0xff << 13 );
     printf("ret %xn",ret);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值