天天看点

位运算的巧妙使用 -- 交换两个值

引言

我们都知道,在程序代码中,位运算的计算时间是比较短的,相比加减法乘除法来说,所以,我们经常会在内核代码,或者一些要求运算速度的场景中看到使用位运算的,接下来就介绍两个位运算的巧妙运用吧。

不使用多余的空间交换两个值

考虑一个 swap 函数,它可以将 a 与 b 的值进行交换,我们可以写出使用指针的版本:

template <typename T>
void swap(T *a, T *b){
                T temp = *a;
          *a = *b;
          *b = temp;
}      

这样看我们其实使用了一个局部变量 temp,那么我们能否在不使用局部变量的情况下实现两个数值的交换呢?我们先来看看第一种简单的方法,使用加减法:

int a = 1;
int b = 2;
//swap by +/-
a = a + b;
b = a - b;        //b = (a + b) - b = a
a = a - b;        //a = (a + b) - b = (a + b) - a = b      

可以发现,这种方法实际上是先将 a+b 赋值给 a,再计算 b(实际上要给 b 赋值之前 a 的值),所以用 a-b 就得到了旧的 a 值,同理,最后一步 a=a-b 也计算出了 b 的值,达成了交换的目的。

int a = 1;
int b = 2;
//swap by ^
a = a ^ b;
b = a ^ b;        //b = (a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a;
a = a ^ b;        //a = (a ^ b) ^ a = a ^ b ^ a = b;