从整数转换为其二进制表示
Posted
技术标签:
【中文标题】从整数转换为其二进制表示【英文标题】:Converting from an integer to its binary representation 【发布时间】:2012-12-01 23:48:37 【问题描述】:有没有人知道 Go 中是否有任何内置功能可以将任何一种数字类型转换为其二进制数形式。
例如,如果123
是输入,则字符串"1111011"
将是输出。
【问题讨论】:
这是自动完成的。十进制数以二进制形式转换和使用。 编程语言中的数字已经以二进制形式存储。也许您的意思是以 2 为基础输出它们?还是 32 位二进制补码基数 2?当然,对于浮点数来说,这两者都没有意义,您想要 IEEE 的文本表示,无论格式如何。还是只是将原始位模式输出到流中? 【参考方案1】:接受答案的另一种方法是简单地做
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)
这也适用于负整数。
【讨论】:
【参考方案2】:此代码适用于大整数*big.Int
:
x := big.NewInt(123)
s := fmt.Sprintf("%b", x)
// s == "1111011"
因为*big.Int
实现了fmt.Formatter
接口。
取自https://***.com/a/23317788/871134
【讨论】:
【参考方案3】: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
【讨论】:
【参考方案4】:必须使用不安全的指针才能正确表示二进制格式的负数。
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
【讨论】:
【参考方案5】:基于@Mark 提供的答案
虽然 OP 询问如何打印整数,但我经常想查看超过 64 位的数据,而不会让我的眼睛难以置信:
/* --- Credit to Dave C in the comments --- */
package main
import (
"bytes"
"fmt"
)
func main()
fmt.Printf("<%s>\n", fmtBits([]byte0xDE, 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()
see this code in play.golang.org
【讨论】:
如果你要硬编码到标准输出,那么就在循环中输出;如果它是一个格式化函数,那么让它返回[]byte
。像这样反复附加到string
效率低下,最好使用bytes.Buffer
之类的东西(或者如果它只使用前导零,则只使用strconv.AppendInt
和普通[]byte
)。在每次迭代中调用strings.TrimSpace
只是为了处理单个额外空间是非常低效的。例如。 play.golang.org/p/ifobZWv_du 之类的东西在 1kB 的输入上要快约 50 倍,并使用约 1/50 的内存。
效率从来没有在我的脑海中浮现,但总的来说你是正确的,你的解决方案比我的要好得多,谢谢!显示超过 64 位的数据是我的目标 :)【参考方案6】:
另见fmt 包:
n := int64(123)
fmt.Printf("%b", n) // 1111011
【讨论】:
正如@Luke Antins 所示,二进制输出的长度可以通过在百分比和 b 之间添加一个数字来指定。例如。 '%08b' 导致 00000001。s := fmt.Sprintf("%b", 123)
【参考方案7】:
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 = 10 的数字值。
【讨论】:
非常感谢...我需要更仔细地阅读手册。 如何格式化负整数(有符号整数),fmt.Println(strconv.FormatInt(n, 2))
是-11
,但我想要两个的恭维格式。
这个反面是什么?如果我需要二进制字符串中的整数?
@majidarif,使用i, err := strconv.ParseInt("1101", 2, 64)
以上是关于从整数转换为其二进制表示的主要内容,如果未能解决你的问题,请参考以下文章
如何在JavaScript中将数字的二进制表示从字符串转换为整数?