二进制补码和 fmt.Printf 令人费解的输出
在计算机科学领域,二进制补码是用来表示的普遍方法内部有符号整数。这种表示涉及翻转位并加一来表示负数。例如,在二进制补码中,-5 将以二进制格式表示为“1111 1011”(相当于 ^5 1)。
尝试使用 fmt.Printf 打印有符号整数的二进制表示形式时会出现困惑。考虑以下代码片段:
var i int8 = -5 fmt.Printf("%b", i)
预期,此代码应输出“1111 1011”,即 -5 的补码表示形式。然而,实际输出是“-101”,这偏离了这个期望。这就提出了一个问题:该值在内部以二进制补码格式存储,还是使用了不同的表示形式?
有趣的是,在打印之前将值转换为无符号整数会产生所需的结果:
var u uint8 = uint(i) fmt.Printf("%b", u)
这会输出“11111011”,即 -5 的精确二进制补码表示。
差异的关键在于 fmt.Printf 如何处理二进制数字的格式。仔细检查 fmt.integer 函数,可以清楚地看到,在格式化过程中,负符号整数被转换为正整数:
165 negative := signedness == signed && a < 0 166 if negative { 167 a = -a 168 }
此转换需要添加“-”前缀格式化字符串,解释了之前观察到的“-101”输出。
本质上,该值的内部表示遵循补码约定,而 fmt.integer 中的格式化过程会转换负符号整数与其正值相对应,导致意想不到的输出。
以上是为什么 fmt.Printf 在 Go 中打印有符号整数的二进制表示时输出“-101”?的详细内容。更多信息请关注PHP中文网其他相关文章!