【问题标题】:Negative integer to binary in Golang [duplicate]Golang中的负整数到二进制[重复]
【发布时间】:2018-11-11 05:41:03
【问题描述】:

如何在 Go 中使用二进制补码表示法将负整数表示为二进制?
例如:

n := int64(-1)
fmt.Printf("%b", n)
fmt.Println(strconv.FormatInt(n, 2))

两行都打印-1。结果应该是ffffffffffffffff

【问题讨论】:

    标签: go binary numeric twos-complement


    【解决方案1】:

    很抱歉,您的意思是要探索 int64 值是如何存储在内存中的吗?您将需要使用 unsafe 包来强制重新解释 go 中的值。

    这段代码做你想做的事:

    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    func main() {
        a := int64(-1)
        fmt.Printf("%x\n", *(*[8]byte)(unsafe.Pointer(&a)))
    }
    

    【讨论】:

    • 哇!它似乎正在工作,但是......没有像其他语言那样更花哨的方式吗? :)
    • Golang 是一种类型安全的语言,这意味着它不允许您将值解释为不兼容的类型(在这种情况下为 int64 到原始字节),而在“其他语言”中则不然例如 C。如果你真的需要这样做,你将不得不使用 unsafe 包来规避这种保护。
    • 不要为此使用包unsafe,只需将其转换为标记副本中显示的无符号整数。仅在确实合理的情况下使用unsafe,并且仅作为最后的手段。
    【解决方案2】:

    我还编写了一个 func 以编程方式计算 int64 的二进制补码符号,以防您只想计算值:

    package main
    
    import (
        "fmt"
        "math/big"
    )
    
    func main() {
        a := int64(-1)
        fmt.Printf("%x\n", TwoComplement(a))
    }
    
    func TwoComplement(val int64) []byte {
        n := big.NewInt(val)
    
        var r []byte
        if n.Cmp(big.NewInt(0)) != -1 {
            r = n.Bytes()
        } else {
            mask := big.NewInt(1)
            mask.Lsh(mask, 64)
    
            r = n.Add(n, mask).Bytes()
        }
    
        res := bytes.NewBuffer([]byte{})
        for i := 0; i < 8-len(r); i++ {
            res.WriteByte(0)
        }
        res.Write(r)
        return res.Bytes()
    }
    

    【讨论】:

    • 也可以使用按位非运算符加1 ^bits+1
    猜你喜欢
    • 1970-01-01
    • 2013-03-28
    • 2018-11-02
    • 1970-01-01
    • 2018-03-30
    • 2014-06-12
    • 2017-07-13
    • 2018-10-10
    • 1970-01-01
    相关资源
    最近更新 更多