Go:将符文(字符串)转换为二进制的字符串表示形式

时间:2015-02-22 14:51:29

标签: string go binary type-conversion

这是为了防止其他人正在学习Golang并且想知道如何将字符串转换为二进制的字符串表示形式。

长话短说,我一直在寻找标准库而无法找到合适的电话。所以我从类似于以下内容开始:

func RuneToBinary(r rune) string {
    var buf bytes.Buffer
    b := []int64{128, 64, 32, 16, 8, 4, 2, 1}
    v := int64(r)
    for i := 0; i < len(b); i++ {
        t := v-b[i]
        if t >= 0 {
           fmt.Fprintf(&buf, "1")
           v = t
        } else {
           fmt.Fprintf(&buf, "0")
        }
    }

    return buf.String()
}

这一切都很好,但是经过几天的回顾,我发现我应该使用fmt包,而只是使用rune格式化%b%

var r rune
fmt.Printf("input: %b ", r)

有更好的方法吗?

由于

1 个答案:

答案 0 :(得分:6)

标准库支持

fmt.Printf("%b", r) - 此解决方案已经非常紧凑,易于编写和理解。如果您需要string的结果,则可以使用模拟Sprintf()函数:

s := fmt.Sprintf("%b", r)

您还可以使用strconv.FormatInt()函数,该函数采用多种类型int64(因此您首先必须转换rune)和一个可以传递2的基数以二进制表示形式获得结果:

s := strconv.FormatInt(int64(r), 2)

请注意,Go rune只是int32的别名,两种类型是同一个(只有两个名称可以引用它)。

手动完成(&#34;简单但天真&#34;):

如果您想要手动操作&#34;,那么解决方案比原始解决方案简单得多。您可以使用r & 0x01 == 0测试最低位,并使用r >>= 1移位所有位。只是&#34;循环&#34;在所有位上添加"1""0",具体取决于位:

请注意,这只是为了演示,它在性能方面远远不够理想(生成&#34;冗余&#34; string s):

func RuneToBin(r rune) (s string) {
    if r == 0 {
        return "0"
    }
    for digits := []string{"0", "1"}; r > 0; r >>= 1 {
        s = digits[r&1] + s
    }
    return
}

注意:函数不处理负数。如果您还想处理负数,可以先检查它并继续使用它的正值,然后使用减号'-'开始返回值。这也适用于下面的其他手动解决方案。

手动性能解决方案:

对于快速解决方案,我们不应该附加字符串。由于Go中的字符串只是使用UTF-8编码的字节片段,因此附加数字只是附加符号'0''1'的字节值,它只是一个字节(不是多个)。所以我们可以分配一个足够大的缓冲区/数组(rune是32位,所以最多32位二进制数字),并向后填充它,所以我们甚至不必在最后反转它。并返回最后转换为string的数组的已使用部分。请注意,我甚至不会调用内置的append函数来附加二进制数字,我只是设置了构建结果的数组的相应元素:

func RuneToBinFast(r rune) string {
    if r == 0 {
        return "0"
    }
    b, i := [32]byte{}, 31
    for ; r > 0; r, i = r>>1, i-1 {
        if r&1 == 0 {
            b[i] = '0'
        } else {
            b[i] = '1'
        }
    }
    return string(b[i+1:])
}