如何使用二进制补码表示Go中的负整数?
例如:
n := int64(-1)
fmt.Printf("%b", n)
fmt.Println(strconv.FormatInt(n, 2))
两行代码均输出
-1
,结果应该像ffffffffffffffff
这样。如何使用二进制补码表示Go中的负整数?
例如:
n := int64(-1)
fmt.Printf("%b", n)
fmt.Println(strconv.FormatInt(n, 2))
-1
,结果应该像ffffffffffffffff
这样。很抱歉,您是否意味着您想探索 int64 值在内存中的存储方式?您需要使用 unsafe
包来强制重新解释 Go 语言中的值。
下面的代码实现了您想要的功能:
package main
import (
"fmt"
"unsafe"
)
func main() {
a := int64(-1)
fmt.Printf("%x\n", *(*[8]byte)(unsafe.Pointer(&a)))
}
我还编写了一个函数,用于以编程方式计算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
。 - Kenpachi
unsafe
包来规避此保护。 - Eternal_flame-ADunsafe
包来处理这个问题,只需按照标记的重复项中所示将其转换为无符号整数即可。仅在确实有必要时才使用unsafe
,并且只作为最后的手段。 - icza