位运算符巧用

使用移位运算符计算一个数的2的次幂的倍数。

n << 1 即等价于 n*2
n >> 1 即等价于 n/2

原理可参考十进制:

n << 1 相当于结尾加个0,等价于 n*10。
n >> 1 相当于结尾去掉一位,等价于 n/10。
注:对于右移,各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)


使用&运算符判断奇偶

printf( n&1 ? "奇数" : "偶数");

不使用临时变量交换两数

异或运算符定义:

两个位相同为0,相异为1。

性质:

1.满足交换律:b^(a^b)=b^b^a
2.一个数和自己异或的结果为0
3.任何数与0异或都不变

利用这三条性质可以证明swap函数的正确性。

void Swap(int &a, int &b)  
{  
   if (a != b)  
   {  
       1.a = a ^ b;  
       2.b = b ^ a;  
       3.a = a ^ b;  
   }  
}

第二条语句先给b赋a的值:

 b = b^(a) = b^(a^b) = b^b^a = a;

第三条语句再给a赋b的值

 a = (a)^(b) = (a^b)^a = a^a^b = b;

求绝对值


int my_abs(int a)
{
    int i = a >> 31;//取符号位
    return i == 0 ? a : (~a + 1);//若为正数,直接返回,否则取反+1
}

利用异或的第三条性质:

3.任何数与0异或都不变

上述代码可优化成秀操作最终版:

int my_abs(int a)
{
    int i = a >> 31;
    return ((a ^ i) - i);
}

防溢出式求两数的平均值

求平均值一般会想到(x+y)/2 ,但x+y可能会溢出,所以用位运算能防止溢出。

int avg=(x&y) +((x^y)>>1);

首先对上式各部分做个解释:

x&y 取出x和y二进制都为‘1’的所有位
x^y x和y中有一个为‘1’的所有位
(x^y)>>1 除以2

思想就是:
就是把x+y的和分成两部分,
一部分是x和y都为‘1’的部分,因为求平均数要相加后除以2,所以把这两个1当作一个1和后面的直接加就行了 。
另一部分是x为‘1’,y为‘0’的部分,以及y为’1‘,x为’0‘的部分,两部分加起来除以2.
然后这两部分的平均值相加就可以了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值