笔记一 2.1.8异或交换产生的问题
Posted 王玉成的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了笔记一 2.1.8异或交换产生的问题相关的知识,希望对你有一定的参考价值。
博客一放,又是好久没有写了。。。。
前两天买了两本砖头书回来。一本是《深入理解计算机系统》第二版的的中文版,另一本便是《算法导论》第三版的中文版。打算花时间认认真真消化完这两本书。再结合自己几年的工作经验,根据理论,做一些分析,力争找到问题的本源,以及解决办法,多写几句没事,争取把问题讲透。另外一点,便是想把不扎实的知识点,通过阅读这本书,把东西吃透。需要整理的代码,自己扔在csdn的git托管中。今天分析的这个代码的源文件是2.1.8-swap.c,可以参考一下。
今天主要是看到书的2.1.8节,C语言的位运算中。聊到了用异或实现a和b数据交换的问题。实际上这个函数在实际应用上,并没有多少价值,但最主要的是加深原理性的理解。
void swap(int *x, int *y)
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
说实话,单看这段代码,也不会出现问题。我原来印象出,一直觉得是溢出会产生的问题。但是自己写代码验证过,溢出并没有产生问题。读了文章中,才反应过来这个函数真的会出现问题。但是如果不是看到练习题2-11,我真的还想不到哪儿出了问题。。。。
异或交换的依据是a^b^a = b,然后有一个加法逆元的结论,a^a= 0。我联想起来,用加减去做swap的一个例子。
void swap2(int *x, int *y)
*x = *x + *y;
*y = *x - *y;
*x = *x - *y;
实现原理也跟加法逆元的概念有关。a+b-a = b,同异或a-a = 0 那么,如果不用第三个数,做数据交换,只要他有加法逆元,即这个数与它本身的运算,结果为0。就可以用做数据交换来使用。
看到还有一句话的实现
a = b+a - ( b=a );
实际上也是用了加法逆元的特性,写法不一样,原理是一样的。
也是正因为这一个特性,导致数组逆序时,产生了问题。在逆序的数组为奇数时,最后变成了自己交换。然后a^a=0的副作用这时候就显现出来了。a-a=0的副作用也同样。。。
书中的要求修改的代码,我也改过,仍然放在2.1.8-swap.c这个文件中,可以做参考。规避掉奇数个的数组逆序时产生的问题。
这个问题就分析到这里,后面力争在每一个问题上,都挖出源头。
以上是关于笔记一 2.1.8异或交换产生的问题的主要内容,如果未能解决你的问题,请参考以下文章