关于位运算的一些小代码

/*关于位运算的一些小代码*/

package main

import "fmt"

// swap 不用任何额外变量,
// 使用异或运算交换两个整数的值
func swap(a, b *int) {
	*a = *a ^ *b
	*b = *a ^ *b
	*a = *a ^ *b
}

// max 不用任何比较判断找出两个数中较大的数
func max(a, b int32) int32 {
	flip := func(n int32) int32 { return n ^ 1 }
	sign := func(n int32) int32 { return flip((n >> 31) & 1) }
	c := a - b
	aSign, bSign, cSign := sign(a), sign(b), sign(c)
	abSignDif := aSign ^ bSign
	abSignSame := flip(abSignDif)
	returnA := abSignDif*aSign + abSignSame*cSign
	returnB := flip(returnA)
	return a*returnA + b*returnB
}

// 整数的二进制表达中有多少个1
func countOne(n int) int {
	result := 0
	for n != 0 {
		n -= n & (^n + 1)
		result++
	}
	return result
}

// 整数的二进制表达中有多少个1(magic)
func countOne2(n int) int {
	n = (n & 0x55555555) + ((n >> 1) & 0x55555555)
	n = (n & 0x33333333) + ((n >> 2) & 0x33333333)
	n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f)
	n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff)
	return (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff)
}

// // 整数的二进制表达中有多少个1(MIT hackmen)
func countOne3(n int) int {
	t := n - ((n >> 1) & 0b11011011011011011011011011011011) -
		((n >> 2) & 0b1001001001001001001001001001001)
	return ((t + (t >> 3)) & 0b11000111000111000111000111000111) % 63
}

// 找到唯一出现奇数次的数
func findOdd(nums []int) int {
	result := 0
	for _, v := range nums {
		result ^= v
	}
	return result
}

func main() {
	a, b := 1, 2
	swap(&a, &b)
	fmt.Println(a, b)
	var c, d int32 = 123, 456
	fmt.Println(max(c, d))
	fmt.Println(countOne(1023), countOne(1024))
	fmt.Println(countOne2(1023), countOne2(1024))
	fmt.Println(countOne3(1023), countOne3(1024))
	fmt.Println(findOdd([]int{1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5}))
}
posted @ 2022-07-24 23:55  Tacey Wong  阅读(34)  评论(0编辑  收藏  举报