Go - 将表示二进制数字的字符串转换为整数

22

我为此写了一个愚蠢的解决方案,有更好的建议吗? 你可以看到那里有很多无用的转换。

package main

import (
    "fmt"
    "strconv"
    "math"
)

func conv(str string) int {
    l := len(str)
    result := 0.0
    for i,n := range str {
        number,_ := strconv.Atof64(string(n))
        result += math.Exp2(float64(l-i-1))*number
    }
    return int(result)
}

func main() {
    fmt.Println(conv("1001"))
}

1
以下答案是推荐的,但如果你真的想自己进行转换,可以不借助任何库来完成。将 result 设为整数类型,在循环的每次迭代中,执行 result = (result<<1)|(n-'0') - axw
3个回答

47

您需要使用strconv.ParseInt函数,它可以将任意进制的数字转换为特定位数的整数。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    if i, err := strconv.ParseInt("1001", 2, 64); err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(i)
    }
}

Playground


8
例如,在Go 1上,
package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, err := strconv.ParseInt("1101", 2, 64)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(i)
}

输出:

13

2
哇,他们确实为Go 1更改了strconv包。 - Lily Ballard
这怎么可能是真的?如果我们将二进制转换为有符号整数(使用ParseInt而不是ParseUint函数),“1101”必须返回“-3”。如果第一位是1,那么意味着数字是负数,不是吗?我错过了什么吗? - igronus
1
@igronus: "我错过了什么吗?" 是的,你错过了。负数的字符串前缀是负号(-)。例如,十进制的 -3,二进制的 -11 - peterSO
@peterSO 真的吗?如果我从某个标记为包含整数的硬件寄存器中读取数据,我得到的是“1101”,它等于“-3”。在二进制数据中没有符号,只有0和1。 - igronus
@igronus:确实。“负数通常用减号表示。”https://en.wikipedia.org/wiki/Negative_number Go的strconv包解析通常情况。您有一个特殊情况:二进制补码表示法。https://en.wikipedia.org/wiki/Two%27s_complement 要解析二进制补码表示法,请编写一个简单的Go函数。https://play.golang.org/p/x_JtICLB6Pv - peterSO
@peterSO 好的,谢谢。对我来说,golang中的二进制文件相当奇怪。 - igronus

0
package main

import (
    "fmt"
)

var digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

func convertBase(num, fromBase, toBase int) string {
    if num == 0 {
        return "0"
    }

    var result []byte

    n := num
    if n < 0 {
        n = -n
        result = append(result, '-')
    }

    var stack []int
    for n > 0 {
        remainder := n % toBase
        stack = append(stack, remainder)
        n /= toBase
    }

    for len(stack) > 0 {
        result = append(result, digits[stack[len(stack)-1]])
        stack = stack[:len(stack)-1]
    }

    return string(result)
}

func main() {
    var num, fromBase, toBase int

    fmt.Print("Enter the number: ")
    fmt.Scanln(&num)

    fmt.Print("Enter the base of origin: ")
    fmt.Scanln(&fromBase)

    fmt.Print("Enter the base destination: ")
    fmt.Scanln(&toBase)

    // Convert from the original base to decimal first
    decimalNum := 0
    n := num
    p := 1
    for n > 0 {
        remainder := n % 10
        decimalNum += remainder * p
        n /= 10
        p *= fromBase
    }

    // Convert the decimal number to the desired base
    result := convertBase(decimalNum, 10, toBase)

    fmt.Printf("%v based on %v = %v based on %v.\n", num, fromBase, result, toBase)
}

目前你的回答不太清楚。请 [编辑] 添加更多细节,以帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到有关撰写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接