当前位置: 首页 > 面试题库 >

使用Go对CPU ID进行位掩码转换

姬英武
2023-03-14
问题内容

我有一个包含cpu_ids的二进制计数(口罩0xA00000800000,我想转换成3级的CPU)string逗号分隔的cpu_ids:"0,2,24"

我执行了以下Go实施(我是Go入门)。这是最好的方法吗?特别是字节缓冲区的处理似乎效率很低!

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main(){
    cpuMap     := "0xA00000800000"
    cpuIds     = getCpuIds(cpuMap)
    fmt.Println(cpuIds)
}

func getCpuIds(cpuMap string) string {
    // getting the cpu ids
    cpu_ids_i, _ := strconv.ParseInt(cpuMap, 0, 64) // int from string
    cpu_ids_b := strconv.FormatInt(cpu_ids_i, 2)    // binary as string

    var buff bytes.Buffer
    for i, runeValue := range cpu_ids_b {
        // take care! go returns code points and not the string    
        if runeValue == '1' {
            //fmt.Println(bitString, i)
            buff.WriteString(fmt.Sprintf("%d", i))
        }
        if (i+1 < len(cpu_ids_b)) && (runeValue == '1') {
            //fmt.Println(bitString)
            buff.WriteString(string(","))
        }

    }
    cpuIds := buff.String()
    // remove last comma
    cpuIds = cpuIds[:len(cpuIds)-1]
    //fmt.Println(cpuIds)
    return cpuIds
}

返回值:

“ 0,2,24”


问题答案:

您要做的实际上"1"是从左至右输出二进制表示形式中的的索引,并从左侧开始计数(不常用)。

您可以使用位掩码和按位运算符来实现相同功能,而无需将其转换为二进制字符串。而且我将返回索引的一部分而不是其格式化的字符串,以便于使用。

要测试最低(最右边)的位是否为1,您可以像一样进行操作x&0x01 == 1,然后将一个整数按位右移:x >>= 1。移位后,最右边的位“消失”,先前的第二位变为第一位,因此您可以使用相同的逻辑再次进行测试。您可以循环播放直到该数字大于0(这意味着底数为1位)。

当然,如果我们测试最右边的位并向右移动,我们将获得 相反 的位(索引)(与所需值相比),并且索引从右开始计数,因此我们必须在返回结果之前对其进行更正。

因此,解决方案如下所示:

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


 类似资料:
  • 问题内容: 位和位掩码是我一直在努力理解的东西,但是我想学习如何在PHP中使用它们进行设置和类似操作。 我终于找到了一个声称完全可以做到这一点的类,而且据我所知,它似乎可以工作,但是我不确定这是否是实现此目的的最佳方法。我将使用下面的示例代码发布类文件,以按工作顺序显示它。 如果您有经验,请告诉我是否可以改进,性能或其他方面。我真的很想学习这一点,而且我一直在阅读它,但是到目前为止,这对我来说很难

  • 我试图找到/创建一个位旋转算法,该算法在-bit-count位掩码中生成s的所有

  • 问题内容: 我有以下几点: 我想了解如何计算得出以下结果,例如: 12414 我对位掩码的工作原理一无所知,如果有人能给出一些提示并解释它如何达到这个数字,我将不胜感激。 问题答案: 该表达式等效于2的n次幂。 您撰写本文时,只要和相同,就不同。因此,您可以根据需要以简单的添加方式来考虑它。 数以二进制是所以它是下列标志的总和(或按位OR): 请注意,当从右到左读取时,包含的标志对应于在12414

  • 问题内容: 我正在使用PHP的用户角色/权限系统来编写脚本。 下面是使用位掩码方法获得phpbuilder.com权限的代码。 在该部分下面是一个简单得多的版本,w3hich可以在几乎没有该部分的情况下完成相同的操作。 许多人建议使用位运算符,例如PHP中的设置和其他内容,但我从来不明白为什么。在下面的代码中,使用第一个代码而不是第二个代码有什么 好处 ? 非位版本 问题答案: 为什么不这样做呢?

  • 我试图了解国际象棋编程中的位板表示是如何工作的,但我找不到关于一个细节的有用信息(或者只是无法正确翻译它^^)。我的问题是,如何自动生成掩码,以便在每个位置上移动每一个棋子。我假设它是一个矩阵,其中每个棋子类型都定义了他可以从该位置移动的每个字段(wP、bP、K、R、N、B的数组[5][64])。例如,对于下面的Rook on位置,只允许位置是: 我假设我必须为每一块类型和每一块瓷砖创建类似的东西