标签:
异或(^) 跟 按位与(&)、按位或(|) 一样是一个位运算符,运算速度自然是很快的。
一般的,它似乎没什么用途。我所知道的它最多就用来加加密,用来交换数值。这里说说使用异或交换数值的一些利弊。
优点: 不需要使用中间变量
一般的交换a,b的值,是使用第三方变量temp
temp = a; a = b; b = temp;
可是有一天突然发现了有异或交换数值的方法,这个方法不需要使用第三方变量
a = a ^ b; b = a ^ b; a = a ^ b;
这个方法的写法也很简单:复制3行a = a ^ b,再把第二行的a换成b,我简直太爱这个方法了,只要能有用到的地方,我都考虑用这个方法,也没有遇到任何问题。
可是今天看到了一篇博客《用异或交换两个整数的陷阱》,试着要分析了一下,分析如下:
假设a,b数值相等,都等于x,值写在括号里
a = a(x) ^ b(x); —> a=0, b=x b = a(0) ^ b(x); —> a=0, b=x a = a(0) ^ b(x); —> a=x, b=x
经过这么3步,最后的结果很正常,并没有如他所说是0
不过,再仔细看,是我理解错了,他的意思是,如果a和b是指向同一个地址的数,即a,b是同一个变量,那么就会出错
a = a(x) ^ a(x) --> a = 0 a = a(0) ^ a(0) --> a = 0 a = a(0) ^ a(0) --> a = 0
所以使用异或交换数值需要注意这个陷阱。
缺点: 并不能加快程序运行
我一直觉得异或运算速度快嘛,交换数值肯定也快,然而确实是这样吗?
我在网上又找到了另一篇博客《用异或来交换两个变量效率分析》,这里引用博客原文的一些观点:
1. 这个所谓的“技巧”在现代的机器上只会更慢(我甚至怀疑它从来就不可能比原始办法快)。原始办法是两次内存读和写,这个"技巧"是六读三写加三次异或(或许编译器可以优化成两读三写加三次异或)。
2. 同样也不能节省内存,因为中间变量 tmp 通常会是寄存器(稍后有汇编代码供分析)。就算它在函数的局部堆栈(stack)上,反正栈已经开在那儿了,也没有进一步的函数调用,根本节约不了一丁点内存。
3. 相反,由于计算步骤较多,会使用更多的指令,编译后的机器码长度会增加。(这不是什么大问题,短的代码不一定快,后面有另外一个例子。)
具体的分析可以去看看他的博客。
So 看上去使用异或交换数值是弊大于利,它的优点似乎是微不足道的,现在的硬件那么发达,节约一个变量空间并没有多大意义,倒不如以这点小小的空间换取时间来得值。知道了这样的事实,我就不再考虑异或来交换数值了,老老实实的使用古老的第三方变量就好了。
标签:
原文地址:http://www.cnblogs.com/zhangguiguang/p/4860766.html