异或在go的实现示例
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 运算符对于按位作、加密和切换值等任务特别有用 ,但是应 谨慎使用它,因为它 有时会降低代码的可读性。
- 点赞
- 收藏
- 关注作者
评论(0)