[Go] byteから特定bitをuintとして取り出す

普段プログラミングをやっていて、byteより小さい塊を扱うことはあまりありません。というか、ありませんでした。

今回、1byteを構成している特定のbitを取り出して数値として扱うことがあるかもしれなかったので、やり方を調べてみました。普段からやっている人には当たり前のことかもしれませんが、わりと新鮮でした。

やりたいことは、1byteの一部のbit(下のコードでは2~5ビット)を取り出して、uint8型の数値にするという内容です。

コードは以下のような感じです。

package main

import "fmt"

func main() {

	var b byte = 0xAA //10101010
	var m byte = 0x3C //00111100

	fmt.Printf("b=%08b\n", b)
	fmt.Printf("m=%08b\n", m)
	fmt.Printf("b&m=%08b\n", b&m)

	// 最下位ビットのインデックスを0として、2~5ビットの値をuint8として取り出す

	// 対象ビットだけをマスクして残す
	// 10101010 & 00111100 = 00101000
	var i = uint8(b & m)

	// 不要な下位ビットをシフトして落とす
	// 00101000 >> 2 → 00001010
	i = i >> 2
	fmt.Printf("i=%d", i)
}

実行すると以下のように表示されます。たしかに真ん中の4bit分を数値として取り出せているようです。

go run main.go
b=10101010
m=00111100
b&m=00101000
i=10


実際には複数のbyte列にまたがった、bit列を取り出す必要があったりすると思います。そのような場合に、上のように書いてしまうと、bitを拾うためのマスク表現がたくさん必要になってしまうような気がしまう。
少なくとも、1byte内で取り出すbit列は連続しているはずなので、両側にシフトして不要部分を落とすというやり方の方が、シンプルになる気がします。こんな感じでしょうか。

	// 両側にシフトして必要部分だけを取り出す
	// まずは、上位ビットを落とす
	var tmp = b2 << 2
	fmt.Printf("%08b\n", tmp)
	
        // 下位ビットを落とす(先に左に2ビットシフトした分を加算)
	tmp = tmp >> (2 + 2)
	fmt.Printf("%08b\n", tmp)
	
        // uint8で取り出す
	i2 := uint8(tmp)
	fmt.Printf("%d\n", i2)

結果は先の場合と同じになりました。

一般的な方法があったりするのだろうか。気になります。

この記事が気に入ったらサポートをしてみませんか?