异或在go的实现示例

举报
码乐 发表于 2025/09/03 08:14:11 2025/09/03
【摘要】 1 简介本文用例子 + 逐位演算来说明 二元按位异或(XOR, ^) 在 Go 中的过程,以速览方式了解该运算过程。异或定义(真值表) 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0异或有两个重要代数性质:a ^ a = 0,a ^ 0 = a,且对换、结合律成立(commutative & associative)。...

1 简介

本文用例子 + 逐位演算来说明 二元按位异或(XOR, ^) 在 Go 中的过程,以速览方式了解该运算过程。

异或定义(真值表)

      0 ^ 0 = 0
      0 ^ 1 = 1
      1 ^ 0 = 1
      1 ^ 1 = 0

异或有两个重要代数性质:a ^ a = 0,a ^ 0 = a,且对换、结合律成立(commutative & associative)。

2 不同数据类型的实例

  • 1 正整数(小位宽)——6 ^ 11

先逐位(二进制)演算(按位对齐):

    a = 6  =  0110
    b =11  =  1011
    a^b    =  1101  -> 十进制 13

编程语言Go 示例

    package main
    import "fmt"

    func main() {
        a := 6
        b := 11
        r := a ^ b
        fmt.Printf("%d ^ %d = %d\n", a, b, r)
        fmt.Printf("a: %04b\n", a)
        fmt.Printf("b: %04b\n", b)
        fmt.Printf("r: %04b\n", r)
    }

输出(概念):

    6 ^ 11 = 13
    a: 0110
    b: 1011
    r: 1101

Python 示例

    a = 6
    b = 11
    r = a ^ b
    print(a, "^", b, "=", r)
    print(f"a: {a:04b}")
    print(f"b: {b:04b}")
    print(f"r: {r:04b}")

输出相同:

  6 ^ 11 = 13
  a: 0110
  b: 1011
  r: 1101

结论: 对于普通小整数,语义一致,结果相同。

  • 2 例二:有符号、小位宽(int8)与负数 —— -5 ^ 3

先逐位(以 8 位二补码表示):

  5 = 00000101

-5 的二补码:先取反 11111010,再 +1 → 11111011

    3 = 00000011

逐位异或:

   11111011   (-5)
  ^00000011   ( 3)

11111000 -> 十进制 (作为 unsigned) = 248
作为 int8:248 - 256 = -8

Go(int8)

    var a int8 = -5
    var b int8 = 3
    r := a ^ b

打印位模式需转为 uint8 来看到“原始比特”

      fmt.Printf("%d ^ %d = %d\n", a, b, r)
      fmt.Printf("a bits: %08b\n", uint8(a))
      fmt.Printf("b bits: %08b\n", uint8(b))
      fmt.Printf("r bits: %08b (as int8: %d)\n", uint8(r), r)

输出(概念):

    -5 ^ 3 = -8
    a bits: 11111011
    b bits: 00000011
    r bits: 11111000 (as int8: -8)

Python

    a = -5
    b = 3
    r = a ^ b

  print(r)            # -8
  print(f"{(r & 0xFF):08b}")  # 11111000 (若按 8 位观察)

Python 得到 -8(数学结果相同),但内部表示与 Go 不同(见下)。

3 例三:跨位宽 / 任意大整数 —— Go(定宽截断) vs Python(任意精度)

考虑 1<<31 与 1<<40 的异或。

直觉(位上不重叠):如果支持任意位宽,结果应为两个位都置 1(等于两数相加)。

  Python(任意精度)
  a = 1 << 31        # 2^31 = 2147483648
  b = 1 << 40        # 2^40 = 1099511627776
  r = a ^ b
  print(r)           # 1099511627776 + 2147483648 = 1101659111424
  print(bin(r))

十进制相加(我在内算得到):

   1,099,511,627,776  (2^40)
  +   2,147,483,648   (2^31)
  = 1,101,659,111,424

(两数二进制位不重叠,XOR 等于和)

  Go(定宽并会截断)
  package main
  import "fmt"

  func main() {
      var a uint32 = 1 << 31
      var b uint64 = 1 << 40
      fmt.Printf("a = %032b (%d)\n", a, a)
      fmt.Printf("uint32(b) = %032b (%d)\n", uint32(b), uint32(b))
      fmt.Printf("a ^ uint32(b) = %032b (%d)\n", a^uint32(b), a^uint32(b))
  }

关键点:uint32(b) 会把 b 截为低 32 位 —— 1<<40 的低 32 位是 0(因为 1<<40 = 1<<8 * 2^32,模 2^32 后为 0)。
因此 a ^ uint32(b) == a(不会产生上面 Python 那种“高位也保留”的结果)。

3 Golang 中的 XOR

在 Go 中, XOR(排他 OR)运算符 由 ^ 符号, 用于 整数的按位运算。如果 两个位中只有一个位是 1,它会将每个位设置为 1。

示例:按位异或

这是一个 简单的示例,演示 了在 Go 中使用 XOR 运算符:

	import“fmt”

  func main() {
  a := 5 //0101 二进制
  b := 3 //0011 二进制

  result := a ^ b //0110 二进制, 即 6
  fmt.Println(result) //输出:6
  }
  • 布尔值的异或

Go 不直接为 布尔值提供逻辑 XOR 运算符。但是,您可以使用 不等式 ( !=) 或逻辑运算符来获得相同的结果。

示例:使用不等式的逻辑异或

	import“fmt”

func main() {
a := true
b := false

result := a != b  //真,因为一个是真的, 另一个是假的
fmt.Println(result) //输出:true
}

示例

	import“fmt”

  func main() {
  a := true
	b := false

  result := (a ||b) && !(a & &; b) 
  //真,因为一个是真的, 另一个是假的
   fmt.Println(result) //输出:true
  }

4 小结

XOR 运算符对于按位作、加密和切换值等任务特别有用 ,但是应 谨慎使用它,因为它 有时会降低代码的可读性。

【版权声明】本文为华为云社区用户翻译文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容, 举报邮箱:cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。