从 32 位中获取一位的值

Get value of one bit from 32 bits

右移后如何应用掩码只得到一位?这取决于你向右移动了多少个位置?

在 32 位结构中,我试图获取第 9 位和第 10 位的值。

x := uint32(11537664)

0000 0000 1011 0000 0000 1101 0000 0000
          ^^

那么对于第9位,如果我右移23位我需要屏蔽一个字节?这似乎隔离了第 9 位,因为我得到的值为 1。

(x >> 23) & 0xff
9th bit...should be 1... looks ok.
00000000000000000000000000000001
0x1  

因此,为了得到应该为 0 的第 10 位,我少移动了一位,这确实使 0 一直向右移动。但是它后面有一个 1 需要被屏蔽。我计算出 1 字节加 1 位作为掩码,但我仍然看到位置 2 的位,所以这是不对的。

(x >> 22) & 0x1ff
10th bit... should be 0, but this shift and mask does not look correct.
00000000000000000000000000000010
                              ^  This bit I don't want. 
0x2

Link 举例: https://play.golang.org/p/zqofCAAKDZz

package main

import (
    "fmt"
)

func bin(i uint32) {
    fmt.Printf("%032b\n", i)
}

func hex(i uint32) {
    fmt.Printf("0x%x\n", i)
}

func show(i uint32) {
    bin(i)
    hex(i)
    fmt.Println()
}

func main() {
    x := uint32(11537664)
    fmt.Println("Data")
    show(x)
    fmt.Println("First 8 bits.")
    show(x >> 24)
    fmt.Println("9th bit...should be 1")
    show((x >> 23) & 0xff)
    fmt.Println("10th bit... should be 0")
    show((x >> 22) & 0x1ff)
}

移位后你得到一个数字0b10,你只需要最低位。那你为什么要用 0x1ff 屏蔽?那有 9 个一位,这将使最低的 9 位保持不变(未屏蔽)。

改为使用 0b01 = 0x01 掩码。这只留下最低位,并将所有其他位归零:

show((x >> 22) & 0x01)

Go Playground 上试用。

另请注意,如果您只想测试某个位是 1 还是 0,则不必进行移位。通过在特定位置包含单个位掩码的适当位掩码进行掩码就足够了。您可以将屏蔽结果与零进行比较。

用于测试第 nth 位的正确位掩码只是 1<<n(其中位从零开始索引)。您要测试的 2 位是 22. 和 23. 位。

看这个例子:

x := uint32(11537664)
fmt.Printf("x      : %032b\n", x)

fmt.Println()
const mask22 = 1 << 22
fmt.Printf("mask22 : %032b\n", mask22)
fmt.Printf("22. bit: %032b %t\n", x&mask22, x&mask22 != 0)

fmt.Println()
const mask23 = 1 << 23
fmt.Printf("mask23 : %032b\n", mask23)
fmt.Printf("23. bit: %032b %t\n", x&mask23, x&mask23 != 0)

它输出(在 Go Playground 上尝试):

x      : 00000000101100000000110100000000

mask22 : 00000000010000000000000000000000
22. bit: 00000000000000000000000000000000 false

mask23 : 00000000100000000000000000000000
23. bit: 00000000100000000000000000000000 true