从整数转换为二进制表示


78

有没有人知道Go中是否有任何内置功能可以将任何一种数字类型转换为其二进制数字形式。

例如,如果123是输入,则字符串"1111011"将是输出。


这是自动完成的。十进制数被转换并以二进制形式使用。
QuentinUK

编程语言中的数字已经以二进制形式存储。也许您的意思是以2为基数输出它们?还是32位二进制补码2?当然,对于浮点数来说,这两者都没有意义,因为无论哪种格式,您都希望IEEE的文本表示形式。还是仅将原始位模式输出到流?
millimoose 2012年

Answers:


114

strconv包有FormatInt,它接受的int64,并允许您指定的基地。

n := int64(123)

fmt.Println(strconv.FormatInt(n, 2)) // 1111011

演示: http : //play.golang.org/p/leGVAELMhv

http://golang.org/pkg/strconv/#FormatInt

func FormatInt(i int64, base int) string

FormatInt返回给定基数i的字符串表示形式,表示2 <= base <=36。结果使用小写字母'a'到'z'表示数字值> = 10。


非常感谢...我需要更仔细地阅读手册。
cobie 2012年

1
如何格式化负整数(带符号整数),fmt.Println(strconv.FormatInt(n, 2))-11,但是我想要二进制补码格式。
Simin Jie '18年

4
这有什么反面?如果我需要二进制字符串中的整数?
majidarif

1
@majidarif,使用 i, err := strconv.ParseInt("1101", 2, 64)
tobi.g

59

另请参见fmt软件包:

n := int64(123)
fmt.Printf("%b", n)  // 1111011

9
如@Luke Antins所示,可以通过在百分比和b之间加一个数字来指定二进制输出的长度。例如,“%08B”导致00000001
托马斯FANKHAUSER

2
s := fmt.Sprintf("%b", 123)
ahuigo


4
package main

import . "fmt"

func main(){
    Printf("%d == %08b\n",0,0)
    Printf("%d == %08b\n",1,1)
    Printf("%d == %08b\n",2,2)
    Printf("%d == %08b\n",3,3)
    Printf("%d == %08b\n",4,4)
    Printf("%d == %08b\n",5,5)
}

结果是:

0 == 00000000
1 == 00000001
2 == 00000010
3 == 00000011
4 == 00000100
5 == 00000101

3

以@Mark提供的答案为基础

尽管OP询问了如何打印整数,但我经常想看的是64位以上的数据,而不会感到困惑:

/* --- Credit to Dave C in the comments --- */
package main

import (
    "bytes"
    "fmt"
)

func main() {
    fmt.Printf("<%s>\n", fmtBits([]byte{0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D, 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D}))

    // OUTPUT:
    // <11011110 10101101 10111110 11101111 11110000 00001101 11011110 10101101 10111110 11101111 11110000 00001101>
}

func fmtBits(data []byte) []byte {
    var buf bytes.Buffer
    for _, b := range data {
        fmt.Fprintf(&buf, "%08b ", b)
    }
    buf.Truncate(buf.Len() - 1) // To remove extra space
    return buf.Bytes()
}
在play.golang.org中看到此代码

1
如果您要对标准输出进行硬编码,则只需在循环中输出即可;如果它是格式化函数,则将其返回[]byte。一再追加到string这样是低效的,更好的是使用像一个bytes.Buffer(或者如果只是它没有前导零,只使用strconv.AppendInt了普通的[]byte)。strings.TrimSpace仅仅为了处理单个额外空间而调用每次迭代是非常低效的。例如,在1kB输入上,诸如play.golang.org/p/ifobZWv_du之类的内容快大约50倍,并占用大约1/50的内存。
Dave C

效率从来没有让我发疯,但是从所有方面来说,您都是正确的,并且您的解决方案比我的要好得多,谢谢!我的目标是显示更多,然后是64位数据:)
卢克·安廷斯

2

接受答案的另一种方法是简单地

s := fmt.Sprintf("%b", 123)
fmt.Println(s)                 // 1111011

对于更丰富的表示形式,您可以使用该unsafe软件包(强烈建议不要使用)

a := int64(123)
byteSliceRev := *(*[8]byte)(unsafe.Pointer(&a))
byteSlice := make([]byte, 8)
for i := 0; i < 8; i++ {
    byteSlice[i] = byteSliceRev[7 - i]
}
fmt.Printf("%b\n", byteSlice)

这也适用于负整数。


1

必须使用不安全的指针以二进制格式正确表示负数。

package main

import (
    "fmt"
    "strconv"
    "unsafe"
)

func bInt(n int64) string {
    return strconv.FormatUint(*(*uint64)(unsafe.Pointer(&n)), 2)
}

func main() {
    fmt.Println(bInt(-1))
}

https://play.golang.org/p/GxXjjWMyC4x

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.