所以计算机使用二的补码在内部表示有符号的整数。即-5表示为^5 +1=“11111011”。
但是,尝试打印二进制表示,例如以下代码:
var i int8 = -5
fmt.Printf("%b", i)
输出-101
。和我想的不太一样。是格式不同,还是不使用二的补码?
有趣的是,转换为无符号int会产生“正确”的位模式:
var u uint8 = uint(i)
fmt.Printf("%b", u)
输出是11111011
--恰好是-5
的2补码。
所以在我看来,它的值在内部实际上是使用2的补码,但是格式是打印无符号的5
并在前面加上一个-
。
有人能澄清这一点吗?
发布于 2016-06-02 12:46:14
我相信答案在于fmt
模块如何格式化二进制数,而不是内部格式。
如果您查看一下fmt.integer
,该函数执行的第一个操作之一就是将负号整数转换为正整数:
165 negative := signedness == signed && a < 0
166 if negative {
167 a = -a
168 }
然后,在输出here的字符串前面附加-
。
IOW -101
实际上是以二进制形式附加到5
后面的-
。
注意:fmt.integer
是从print.go中的pp.fmtInt64
调用的,本身也是从同一函数中的pp.printArg
调用的。
发布于 2021-07-07 06:18:59
下面是一种不使用unsafe
的方法
package main
import (
"fmt"
"math/bits"
)
func unsigned8(x uint8) []byte {
b := make([]byte, 8)
for i := range b {
if bits.LeadingZeros8(x) == 0 {
b[i] = 1
}
x = bits.RotateLeft8(x, 1)
}
return b
}
func signed8(x int8) []byte {
return unsigned8(uint8(x))
}
func main() {
b := signed8(-5)
fmt.Println(b) // [1 1 1 1 1 0 1 1]
}
在这种情况下,您也可以使用[8]byte
,但如果您有一个正整数,并且想要修剪前导零,那么上面的方法会更好。
发布于 2019-04-24 03:14:07
必须使用不安全指针以二进制格式正确表示负数。
package main
import (
"fmt"
"strconv"
"unsafe"
)
func bInt8(n int8) string {
return strconv.FormatUint(uint64(*(*uint8)(unsafe.Pointer(&n))), 2)
}
func main() {
fmt.Println(bInt8(-5))
}
输出
11111011
https://stackoverflow.com/questions/37582550
复制相似问题