【发布时间】: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
如何在 Go 中使用二进制补码表示法将负整数表示为二进制?
例如:
n := int64(-1)
fmt.Printf("%b", n)
fmt.Println(strconv.FormatInt(n, 2))
两行都打印-1。结果应该是ffffffffffffffff。
【问题讨论】:
标签: go binary numeric twos-complement
很抱歉,您的意思是要探索 int64 值是如何存储在内存中的吗?您将需要使用 unsafe 包来强制重新解释 go 中的值。
这段代码做你想做的事:
package main
import (
"fmt"
"unsafe"
)
func main() {
a := int64(-1)
fmt.Printf("%x\n", *(*[8]byte)(unsafe.Pointer(&a)))
}
【讨论】:
unsafe 包来规避这种保护。
unsafe,只需将其转换为标记副本中显示的无符号整数。仅在确实合理的情况下使用unsafe,并且仅作为最后的手段。
我还编写了一个 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()
}
【讨论】:
^bits+1