码迷,mamicode.com
首页 > 其他好文 > 详细

异或交换数值的分析

时间:2015-10-12 12:05:33      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

  异或(^) 跟 按位与(&)、按位或(|) 一样是一个位运算符,运算速度自然是很快的。

  一般的,它似乎没什么用途。我所知道的它最多就用来加加密,用来交换数值。这里说说使用异或交换数值的一些利弊。

优点: 不需要使用中间变量

  一般的交换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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!