C/C++位运算技巧 (二)

2014-11-24 01:24:06 · 作者: · 浏览: 8
第三变量)
不用第三个变量交换两个数的方法也有几种,例如a = a + b; b = a - b; a = a - b。下面这种方法可以实现的基础是一个数m与另一个数n异或,再与n异或,得到的结果是m.


[cpp]
/*
不适用临时变量,交换两个数
a = a ^ b
b = b ^ a
a = a ^ b
*/
void mySwap(int* a,int* b)
{
(*a) ^= (*b) ^= (*a) ^= (*b);
}

/*
不适用临时变量,交换两个数
a = a ^ b
b = b ^ a
a = a ^ b
*/
void mySwap(int* a,int* b)
{
(*a) ^= (*b) ^= (*a) ^= (*b);
}

求一个数的绝对值
下面的方法实现的基础是将n右移31位,可以获得n的符号。


[cpp]
/*
取绝对值
n右移31位,可以获得n的符号。若n为正数,得到0;若n为负数,得到 -1

*/
int myAbs(int n){
return (n ^ n >> 31) - (n >> 31);
}

/*
取绝对值
n右移31位,可以获得n的符号。若n为正数,得到0;若n为负数,得到 -1

*/
int myAbs(int n){
return (n ^ n >> 31) - (n >> 31);
}

求两个数的平均值
第一种方法较为普遍且简单,不多说了。第二种方法,需要知道的是,( m ^ n ) >> 1得到的结果是m和n其中一个数的有些位为1的值的一半,m & n得到的结果是m 和n都为1的那些位,两个结果相加得到m和n的平均数。


[cpp]
/*
求m和n的平均数
*/
int getAverage(int m,int n){
return (m + n) >> 1;
}

/*
求m和n的平均数
(m ^ n) >> 1 -> 获得m和n两个数中一个数的某些位为1的一半
m & n -> 获得m和n两个数中都为1的某些位
*/
int getAverage_2(int m,int n){
return ((m ^ n) >> 1) + (m & n);
}

/*
求m和n的平均数
*/
int getAverage(int m,int n){
return (m + n) >> 1;
}

/*
求m和n的平均数
(m ^ n) >> 1 -> 获得m和n两个数中一个数的某些位为1的一半
m & n -> 获得m和n两个数中都为1的某些位
*/
int getAverage_2(int m,int n){
return ((m ^ n) >> 1) + (m & n);
}

求解倒数第m位相关问题

[cpp]
/*
获取n的倒数第m位的值(从1开始计数)
*/
int getMthByTail(int n,int m){
return (n >> (m - 1)) & 1;
}

/*
将n的倒数第m位设为1
*/
int setMthByTail21(int n,int m)
{
return n | (1 << (m - 1));
}

/*
将n的倒数第m位设为0
*/
int setMthByTail20(int n,int m)
{
return n & ~(1 << (m - 1));
}

/*
获取n的倒数第m位的值(从1开始计数)
*/
int getMthByTail(int n,int m){
return (n >> (m - 1)) & 1;
}

/*
将n的倒数第m位设为1
*/
int setMthByTail21(int n,int m)
{
return n | (1 << (m - 1));
}

/*
将n的倒数第m位设为0
*/
int setMthByTail20(int n,int m)
{
return n & ~(1 << (m - 1));
}