はじめに
Go1.9でmath/bits
パッケージとして様々なビット演算を行う関数が実装されたので使用例をご紹介します!
Note:
XXはビット数を表し、8, 16, 32, 64のいずれかを指定することでuintXX型の引数をとることができます。またXXを指定せずに、uint型の引数をとることもできます。
もくじ
- LeadingZerosXX
- TrailingZerosXX
- LenXX
- OnesCountXX
- ReverseXX
- ReverseBytesXX
- RotateLeftXX
func LeadingZerosXX(x uintXX) int
- xを2進数で表したとき、左側から見て0がいくつ続いているか(いわゆるclz)
bits.LeadingZeros16(0)
// => 16
$\underbrace{0000000000000000}_{16}$
bits.LeadingZeros16(1)
// => 15
$\underbrace{000000000000000}_{15}1$
bits.LeadingZeros16(256)
// => 7
$\underbrace{0000000}_{7}100000000$
bits.LeadingZeros16(65535)
// => 0
$\underbrace{}_{0}1111111111111111$
func TrailingZerosXX(x uintXX) int
- xを2進数で表したとき、右から見て0がいくつ続いているか(いわゆるctz)
bits.TrailingZeros16(0)
// => 16
$\underbrace{0000000000000000}_{16}$
bits.TrailingZeros16(1)
// => 0
$0000000000000001\underbrace{}_{0}$
bits.TrailingZeros16(256)
// => 8
$00000001\underbrace{00000000}_{8}$
bits.TrailingZeros16(65535)
// => 0
$1111111111111111\underbrace{}_{0}$
func LenXX(x uintXX) int
- xを表現するのに必要な最小のビット数
bits.Len16(0)
// => 0
$0000000000000000\underbrace{}_{0}$
bits.Len16(1)
// => 1
$000000000000000\underbrace{1}_{1}$
bits.Len16(256)
// => 9
$0000000\underbrace{100000000}_{9}$
bits.Len16(65535)
// => 16
$\underbrace{1111111111111111}_{16}$
func OnesCountXX(x uintXX) int
- xを2進数で表したとき立っているビットの数(いわゆるpopcnt)
bits.OnesCount16(0)
// => 0
$0000000000000000$
bits.OnesCount16(1)
// => 1
$000000000000000\dot{1}$
bits.OnesCount16(256)
// => 1
$0000000\dot{1}00000000$
bits.OnesCount16(65535)
// => 16
$\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}\dot{1}$
func ReverseXX(x uintXX) uintXX
- xの2進数表現を逆順にする
bits.Reverse16(0)
// => 0
$~~~~~ (0000000000000000)_2 = 0$
$\to (0000000000000000)_2= 0$
bits.Reverse16(1)
// => 32768
$~~~~~ (0000000000000001)_2 = 1$
$\to (1000000000000000)_2 = 32768$
bits.Reverse16(256)
// => 128
$~~~~~ (0000000100000000)_2 = 256$
$\to (0000000010000000)_2 = 128$
bits.Reverse16(65535)
// => 65535
$~~~~~ (1111111111111111)_2 = 65535$
$\to (1111111111111111)_2 = 65535$
func ReverseBytesXX(x uintXX) uintXX
- xの2進数表現をバイト(8ビット)単位で逆順にする(いわゆるbswap)
bits.ReverseBytes16(0)
// => 0
$~~~~~ (00000000~~00000000)_2 = 0$
$\to (00000000~~00000000)_2= 0$
bits.ReverseBytes16(1)
// => 256
$~~~~~ (00000000~~00000001)_2 = 1$
$\to (00000001~~00000000)_2= 256$
bits.ReverseBytes16(256)
// => 1
$~~~~~ (00000001~~00000000)_2 = 256$
$\to (00000000~~00000001)_2= 1$
bits.ReverseBytes16(65535)
// => 65535
$~~~~~ (11111111~~11111111)_2 = 65535$
$\to (11111111~~11111111)_2 = 65535$
func RotateLeftXX(x uintXX, k int) uintXX
- xをkだけ左循環シフトする(kだけ右循環シフトしたい場合は-kとする)
bits.RotateLeft16(0, 3)
// => 0
$~~~~~ (0000000000000000^{←3})_2 = 0$
$\to (0000000000000000)_2 = 0$
bits.RotateLeft16(1, 3)
// => 8
$~~~~~ (0000000000000001^{←3})_2 = 1$
$\to (0000000000001000)_2 = 8$
bits.RotateLeft16(256, 3)
// => 2048
$~~~~~ (0000000100000000^{←3})_2 = 256$
$\to (0000100000000000)_2 = 2048$
bits.RotateLeft16(65535, 3)
// => 65535
$~~~~~ (1111111111111111^{←3})_{2} = 65535$
$\to (1111111111111111)_2 = 65535$
bits.RotateLeft16(0, -3)
// => 0
$~~~~~ (0000000000000000^{3→})_2 = 0$
$\to (0000000000000000)_2 = 0$
bits.RotateLeft16(1, -3)
// => 8192
$~~~~~ (0000000000000001^{3→})_2 = 1$
$\to (0010000000000000)_2 = 8192$
bits.RotateLeft16(256, -3)
// => 32
$~~~~~ (0000000100000000^{3→})_2 = 256$
$\to (0000000000100000)_2 = 32$
bits.RotateLeft16(65535, -3)
// => 65535
$~~~~~ (1111111111111111^{3→})_2 = 65355$
$\to (1111111111111111)_2 = 65355$