【问题标题】:Converting from an integer to its binary representation从整数转换为其二进制表示
【发布时间】:2012-12-01 23:48:37
【问题描述】:

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

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

【问题讨论】:

  • 这是自动完成的。十进制数以二进制形式转换和使用。
  • 编程语言中的数字已经以二进制形式存储。也许您的意思是以 2 为基础输出它们?还是 32 位二进制补码基数 2?当然,对于浮点数来说,这两者都没有意义,您想要 IEEE 的文本表示,无论格式如何。还是只是将原始位模式输出到流中?

标签: binary go numeric


【解决方案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://stackoverflow.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([]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()
          }
          
          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)
          猜你喜欢
          • 1970-01-01
          • 2015-11-30
          • 2016-10-12
          • 2021-12-07
          • 2015-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-27
          相关资源
          最近更新 更多