一.位运算符
运算名 | 符号 | 效果 | 使用 | 备注 |
---|---|---|---|---|
按位与 | & | 两数同一个二进制位相与,结果:同1为1,否则为0 | m&n | 无 |
按位或 | | | 两数同一个二进制为相或,结果:同0为0,否则为1 | m|n | 无 |
按位异或 | ^ | 两数同一个二进制为相异或,结果:不同为1,相同为0 | m^n | 无 |
取反 | ~ | 单数各二进制为1变0,0变1 | ~n 或 (^n) | golang的取反操作符为^,作为单目运算符放置于数值的左侧使用,取反操作会连同符号位一起操作 |
左移 | << | 左移1位相等于原数*2 | m<<n | 无 |
右移 | >> | 右移1位相当于原数/2 | m>>n | 无 |
位清空 | &^ | 二进制第n位置0 | m&^n | golang独享 |
二. 一些规则
正数的补码 = 其反码 = 其原码的值
负数的原码 = 该数的绝对值的原码最高位置1后的值
负数的反码 = 其最高位之外的所有位按位取反后整体的值
负数的补码 = 其反码 + 1 的值
三.奇淫技巧
1. 加1
n = 1
n = -( ^n )
2. 减1
n = 3
n = ^(-n)
3. 将m的第n位置为1
m |= 1 << n
4. 清除m的第n位
m &= ^( 1 << n )
m &^= 1 << n
5. 二进制中最左侧的1
func LeftOne(n int64) int64 {
n |= n >> 1 // | 左移1位的数时 高位 前2位 为 11
n |= n >> 2 // | 左移2位的数时 高位 前4位 为 1111
n |= n >> 4 // 以此类推
n |= n >> 8
n |= n >> 16
n |= n >> 32
return (n + 1) >> 1
}
6. 二进制中最右侧的1
rightOne = n & (^n + 1)
rightOne = n & -n
7. 求相反数
m = ( ^n + 1 )
8. 交换两个数。 若a,b为同一变量,会导致a被清零!
a = a ^ b
b = a ^ b
a = a ^ b
9. 判断两数是否异号
(x ^ y) < 0
//true 为异号
//false 为同号
10. 判断一个数是不是 2 的指数
func isPowerOfTwo(n int) bool {
if n <= 0 {
return false
}
return (n & (n - 1)) == 0
}
11. 汉明码距离(二进数中1的个数)
func hammingWeight(n uint32) int {
res := 0
for n != 0 {
n = n & (n - 1)
res++ // res = - (^res)
}
return res
}
12. 判断奇偶数
(n & 1) == 1 //奇数
(n & 1) == 0 //偶数
13. 快速幂
func pow(a, b int64) int64 { // 时间复杂度 O(logN) 溢出会返回 0
res := int64(1)
tmp := a
for b != 0 {
if b&1 == 1 {
res *= tmp
}
tmp *= tmp // 让 tmp 滚动
b >>= 1
}
return res
}
14. 判断是否是2的整数次幂
func isPowerOfTwo(n int) bool {
return n > 0 && n&(n-1) == 0
}
15. 翻转二进制位
func reverseBits(n uint32) (rev uint32) {
for i := 0; i < 32 && n > 0; i++ {
rev |= n & 1 << (31 - i)
n >>= 1
}
return
}
16. 取绝对值
func abs(a int) int {
i := a >> 31
if i == 0 {
return a
}
return ^a + 1
}
func abs(a int) int {
i := a >> 31
return (a ^ i) - i
}
17. 英文字符转换小写 ‘A’ 按位或 空格
'a' | ' '
'A' | ' '
18. 英文字符转换大写 ‘a’ 按位与 下划线
'a' & '_'
'A' & '_'
19. 英文字符大小写互换 ‘A’ 异或 空格
'a' ^ ' '
'A' ^ ' '
20. 清空低位1
n = n & (n-1)
21. 获取m第n位的值
value = (m >> n) & 1
22. 获取m第n位的幂值
value = m & (1 << n)
23. 将m最高位至第n位(含)置0
value = m & ((1 << n) - 1)
24. 将m第n位至第0位(含)置0
value = m & (~((1 << (n + 1)) - 1))
25. 将m高低n位互换
a = (m >> n) | (m << n);
26. a,b 的最大值
func maximum(a int, b int) int {
ret := int64(a-b)
ret = int64(a)-ret&(ret>>63)
return int(ret)
}
27. 加法
func add(a int, b int) int {
var carry int // 进位
for b != 0 {
carry = (a & b) << 1 // 进位
a ^= b // 无进位加
b = carry // 加进位
}
return a
}
28. 清空x的某些位
z = x &^ y //x对应y为1的位会变成0
29. 检查平台uint类型的位数
32 << (^uint(0) >> 63) //32 or 64