位运算的秒用--异或运算

开发 前端
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。(这特么是啥?)没明白没有关系。

先来看一个case

咱们今天闲话不用多说,先来看一个小例子。

如何交换两个数?

问题当然很简单,交换两个数,常规的做法是引入一个中间变量,代码如下

func Swap(a, b int){
temp := a //把a的值赋值给临时变量temp,temp为a的值
a = b //把b的值赋值给a,现在a的值已经变成了b的值
b = temp // 再把之前temp中保存的a赋值给b即可
}

相信上面的代码大家应该都没问题,但是咱们来加大问题难度,如果不让引入第三个变量temp,能实现两个数字的交换么?

「建议大家先思考两分钟再往下看」。

其实很简单,代码如下:

func Swap(a, b int) {
a = a ^ b
b = a ^ b
a = a ^ b
}

相信您现在应该和我第一次看到这个代码的感觉一样,这特么是啥?????这样能把a和b的值交换?

先不要着急,咱们来一点一点的分析。

异或运算

想要看懂上面的代码,首先你得知道什么叫异或运算。

先看定义

如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。(这特么是啥?)没明白没有关系,咱们接下来看例子:

举个例子

比如a=5,b=3。

  • 首先 你得把a和b转换成二进制,那么a=101, b= 011。
  • 然后a和b进行异或运算,一位一位的去对比,如果值相同,则对应位置异或运算的结果为0,如果值不同,则对应位置异或运算的结果为1。

异或运算示意图

  • 所以a和b的异或运算的结果为 110 也就是6。
  • 异或运算也可以按照另外一个角度去理解,就是「无进位的加法」,其实也就是二进制的相加,但是加完的结果不进位而已。

异或运算的特点

0和任何数N进行异或运算,结果为N

其实这个很好理解,任何数转换成二进制,每一位上的数字要么是0,要么是1,而和0进行异或,以前是0的位置和0相同,则结果为0,以前是1的位置和0不同,则结果为1,所以运算之后结果是没变的,如下图:

任何数和0进行异或运算

任何数N和自己进行异或运算,结果为0

这个也很好理解,N^N每一位肯定都会是一样的,根据异或运算的法则,结果肯定每一位都为0。

任何数和自己进行异或运算

异或运算满足交换律和结合律

这个很好理解 也就是说 a^b^c运算 和c^b^a是一样的。

再来看开头的例子

当你对异或运算有一定的了解了之后,咱们再来看一看开头的例子:

func Swap(a, b int) {
a = a ^ b
b = a ^ b
a = a ^ b
}

第一步运算:

a = a ^ b

第二步运算:

b = a ^ b
因为第一步a=a^b所以在第二步中直接把a替换成a^b即可

所以:

b = a ^ b ^ b

咱们在之前说过,「任何数字对自己进行异或运算的结果都为0」,所以b^b的结果就为0,上面也就等价于。

b= a^0

咱们在上面还说过,「任何数和0进行异或运算,都等于他自己」,所以:

b=a^0 = a

第三步运算:

a = a ^ b

此时b已经运算出来为a,a = a ^ b(第一步运算赋值) 所以第三步运算等价于。

a = a^b^a = 0^b = b(运算细节同第二步)

这样咱们就可以不用第三个变量进行两个变量的交换了。

责任编辑:姜华 来源: 程序员小饭
相关推荐

2022-05-23 15:02:19

异或运算面试真题

2021-11-10 09:57:02

异或运算应用

2022-08-01 08:12:14

位运算代码性能

2020-03-25 10:44:16

位运算操作技巧

2021-02-21 06:36:57

运算技巧按位

2017-08-29 09:40:26

JavaScript代码神经网络

2021-10-11 09:41:20

React位运算技巧前端

2009-07-31 16:48:44

C#位运算

2011-08-29 15:53:04

Lua位运算

2009-08-12 10:20:52

C#位运算符

2023-04-07 08:02:54

源码位逻辑运算符

2009-06-18 13:06:59

C#位运算权限管理

2021-01-23 12:22:59

位运算编程语言开发

2018-07-29 15:27:04

AI训练光速运算人工智能

2009-08-12 10:47:03

C#运算符重载

2020-11-09 10:01:29

Python乘法位运算

2009-06-11 16:11:26

Java运算器一则运算

2009-07-21 09:31:00

Scala数学运算逻辑操作位操作符

2023-04-10 08:58:13

C#关系运算符

2009-08-11 15:51:08

C#运算符算术运算符
点赞
收藏

51CTO技术栈公众号