英文:
Convert a hexadecimal number to binary in Go and be able to access each bit
问题
我目前正在研究Go语言,并遇到了一个问题,我想得到一些反馈和帮助
我的问题是,我有一个包含十六进制值的字符串作为输入,例如:
"60A100"
现在,我想将其转换为该数字的二进制表示,并能够查看特定位。
我目前的解决方案是:
i, err := strconv.ParseUint(rawHex, 16, 32)
if err != nil {
fmt.Printf("%s", err)
}
// 将整数转换为二进制表示
// %024b 表示基数为2,使用0填充,共24个字符。
bin := fmt.Sprintf("%024b", i)
变量bin现在正好包含我想要的内容,但它是一个字符串,我认为这不是最优的。我更希望能够有一个包含各个位的数组,这样我就可以通过选择索引i来获取第i位的值
因为据我目前所知,如果我像这样查找索引8;bin[8],我将得到一个对应于二进制数在ASCII表中的十进制值。
我已经搜索了很多,但我找不到完全符合要求的解决方案,也许我在错误的地方寻找。
希望你们能够指导我找到正确/最优的解决方案
提前感谢!
英文:
I am fiddling around with Go at the moment and have stumpled upon a problem where I want to get some feedback and help
My problem is that I have a string containing a hexadecimal value as input, such as this:
"60A100"
Now, I want to convert this to the binary representation of the number and be able to look at specific bits within.
My solution to this right now is:
i, err := strconv.ParseUint(rawHex, 16, 32)
if err != nil {
fmt.Printf("%s", err)
}
// Convert int to binary representation
// %024b indicates base 2, padding with 0, with 24 characters.
bin := fmt.Sprintf("%024b", i)
The variable bin now holds exactly what I want, except it is a string which I don't think is optimal. I would rather that I could have an array of the individual bits such that I could just choose index i to get bit number i
Because as far as I know right now, if I lookup index 8 like so; bin[8], I will get a decimal that corresponds to the binary number, in the ASCII table.
I have searched quite a bit, but I can't find a solution that fits perfectly, but maybe I am looking in the wrong spot.
I hope you guys can guide me to the correct / optimal solution in this case
Thanks in advance!
答案1
得分: 2
在解析值之后,您可以直接访问每个位。您可以使用类似以下的代码:
func getNthBit(val, n uint32) int {
n = 32 - n
if 1 << n & val > 0 {
return 1
}
return 0
}
这段代码可以用来获取给定值 val
的第 n
位。
英文:
After parsing the value you can directly access each bit. You can use something like this:
func getNthBit(val, n uint32) int {
n = 32 - n
if 1 << n & val > 0 {
return 1
}
return 0
}
答案2
得分: 2
你可以将其转换为表示位的切片。
// 这也可以返回 []bool
func asBits(val uint64) []uint64 {
bits := []uint64{}
for i := 0; i < 24; i++ {
bits = append([]uint64{val & 0x1}, bits...)
// 或者
// bits = append(bits, val & 0x1)
// 取决于你想要的顺序
val = val >> 1
}
return bits
}
func main() {
rawHex := "60A100"
i, err := strconv.ParseUint(rawHex, 16, 32)
if err != nil {
fmt.Printf("%s", err)
}
fmt.Printf("%024b\n", i)
fmt.Println(asBits(i))
}
输出
011000001010000100000000
[0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0]
https://play.golang.org/p/KK_AUPgbZu
正如 @jimb 指出的那样,你也可以检查单个位。
fmt.Printf("第9位是否设置?%t\n", (i >> 8) & 1 == 1)
这就是 @n-carter 的答案所做的。
英文:
You could turn it into a slice representing bits
// This could also return []bool
func asBits(val uint64) []uint64 {
bits := []uint64{}
for i := 0; i < 24; i++ {
bits = append([]uint64{val & 0x1}, bits...)
// or
// bits = append(bits, val & 0x1)
// depending on the order you want
val = val >> 1
}
return bits
}
func main() {
rawHex := "60A100"
i, err := strconv.ParseUint(rawHex, 16, 32)
if err != nil {
fmt.Printf("%s", err)
}
fmt.Printf("%024b\n", i)
fmt.Println(asBits(i))
}
OUTPUT
011000001010000100000000
[0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0]
https://play.golang.org/p/KK_AUPgbZu
As @jimb points out, you can also just check an individual bit
fmt.Printf("9th bit is set? %t\n", (i >> 8) & 1 == 1)
which is what @n-carter's answer does.
答案3
得分: 2
根据 @n-carter 的回答,你可以单独访问每个位。
有两种方法:
选项1:移动 value
:
将二进制数向右移动 n
位,以获取第 n 位。然后与 1 进行掩码操作。
func getNthBit(val, n uint32) int {
// 1. 反转 golang 的字节序
nthBit := 32-n
// 2. 将第 n 位移动到第一位
movedVal := val >> nthBit
// 3. 对值进行掩码操作,只选择第一位
maskedValue := movedVal & 1
return maskedValue
// 可以简写为
// return (val >> (32-n)) & 1
}
解释:
1. 根据字节序获取正确的位索引
01100000101000010000000001000101
^
(32-3)=29 位
2. 移动位,将第 n 位移动到第一位
01100000101000010000000001000101 >> 29
^^^
00000000000000000000000000000011
^^^
3. 对第一位进行掩码操作,提取该位的值
00000000000000000000000000000011
& ^
00000000000000000000000000000001
1
选项2:移动 1 并与之进行掩码操作
这可以像 @n-carter 所做的那样完成。将 1 向左移动。
func getNthBit(val, n uint32) int {
// 1. 反转 golang 的字节序
nthBit := 32-n
// 2. 将掩码 1 位移动到第 n 位
mask := 1 << nthBit
// 3. 对值进行掩码操作,只选择第 n 位
maskedValue := val & mask
if maskedValue == 0 {
return 0
}
return 1
// 可以简写为:
// if val & (1 << (32-n)) == 0 {
// return 0
// }
// return 1
}
解释:
1. 根据字节序获取正确的位索引
01100000101000010000000001000101
^
(32-3)=29 位
2. 将 1 移动到第 n 位 (1 << 29 == 2^(29-1))
00000000000000000000000000000001 << 29
00100000000000000000000000000000
3. 对第 n 位进行掩码操作,提取该位的值
01100000101000010000000001000101
&
00100000000000000000000000000000
1
希望对你有所帮助。在脑海中可视化位操作可能需要一些时间。
英文:
Following @n-carter answer, you can access each bit individually
There are two approaches:
Option 1: Shifting the value
:
Shift the bin number to the right n
possitions to get the n-th bit the first one. then mask it with 1
func getNthBit(val, n uint32) int {
// 1. reverse the golang endian
nthBit := 32-n
// 2. move the nth bit to the first position
movedVal := val >> nthBit
// 3. mask the value, selecting only this first bit
maskedValue := movedVal & 1
return maskedValue
// can be shortened like so
// return (val >> (32-n)) & 1
}
Explanation:
1. Get the right bit index according to the endian
01100000101000010000000001000101
^
(32-3)=29nth bit
2. Shift the bits to get n-th in the first possition
01100000101000010000000001000101 >> 29
^^^
00000000000000000000000000000011
^^^
3. Mask first bit. This picks(extracts) the value from this bit
00000000000000000000000000000011
& ^
00000000000000000000000000000001
1
Option 2: shifting 1 and masking with it
This can be done the way @n-carter does. Shift a 1 to the left
func getNthBit(val, n uint32) int {
// 1. reverse the golang endian
nthBit := 32-n
// 2. move the mask 1 bit to the nth position
mask := 1 << nthBit
// 3. mask the value, selecting only this nth bit
maskedValue := val & mask
if maskedValue == 0 {
return 0
}
return 1
// can be written shorter like:
//if val & (1 << (32-n)) == 0 {
// return 0
//}
//return 1
}
Explanation:
1. Get the right bit index according to the endian
01100000101000010000000001000101
^
(32-3)=29nth bit
2. Shift the 1 to the n-th position (1 << 29 == 2^(29-1))
00000000000000000000000000000001 << 29
00100000000000000000000000000000
3. Mask n-th bit. This picks(extracts) the value from this bit
01100000101000010000000001000101
&
00100000000000000000000000000000
1
Hope this helps. It takes some time to visualise bit operations in your head.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论