我有一个掩码,其中包含cpu_ids的二进制计数(3个CPU的CALayer
),我想将其转换为逗号分隔的0xA00000800000
cpu_ids:string
。
我做了以下Go实现(我是Go的首发)。这是最好的方式吗?特别是字节缓冲区的处理似乎效率低下!
"0,2,24"
返回:
" 0,2,24"
答案 0 :(得分:3)
你正在做的事实上是从左到右输出二进制表示中的"1"
的索引,并从左边开始索引计数(不可用)。 / p>
您可以使用位掩码和按位运算符实现相同的操作,而无需将其转换为二进制字符串。我会返回一段索引而不是格式化的字符串,更容易使用。
要测试最低(最右边)位是1
,可以像x&0x01 == 1
那样进行,并将整数按位向右移动:x >>= 1
。移位后,最右边的位"消失",之前的第2位成为第1位,因此您可以使用相同的逻辑再次测试。您可以循环直到该数字大于0(这意味着它有1位)。
有关按位操作的更多示例,请参阅此问题:Difference between some operators "|", "^", "&", "&^". Golang
当然,如果我们测试最右边的位并向右移动,我们得到 reverse 顺序的位(索引)(与你想要的相比),并且索引是从右边计算的,所以我们在返回结果之前必须纠正这个问题。
所以解决方案看起来像这样:
func getCpuIds(cpuMap string) (r []int) {
ci, err := strconv.ParseInt(cpuMap, 0, 64)
if err != nil {
panic(err)
}
count := 0
for ; ci > 0; count, ci = count+1, ci>>1 {
if ci&0x01 == 1 {
r = append(r, count)
}
}
// Indices are from the right, correct it:
for i, v := range r {
r[i] = count - v - 1
}
// Result is in reverse order:
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return
}
输出(在Go Playground上尝试):
[0 2 24]
如果由于某种原因你需要以逗号分隔string
的结果,这就是你如何获得它:
buf := &bytes.Buffer{}
for i, v := range cpuIds {
if i > 0 {
buf.WriteString(",")
}
buf.WriteString(strconv.Itoa(v))
}
cpuIdsStr := buf.String()
fmt.Println(cpuIdsStr)
输出(在Go Playground上尝试):
0,2,24