Golang:二进制补码和fmt.Printf

因此,计算机使用二进制补码在内部表示带符号整数。 即-5表示为^ 5 +1 =“ 1111 1011”。</ p>

但是,尝试打印二进制表示形式,例如 以下代码:</ p>

  var i int8 = -5 
fmt.Printf(“%b”,i)
</ code> </ pre>

输出 -101 </ code>。 不完全符合我的期望。 格式是否不同还是毕竟不使用二进制补码?</ p>

有趣的是,转换为无符号int会导致“正确”位模式:</ p>

< pre> var u uint8 = uint(i)
fmt.Printf(“%b”,u)
</ code> </ pre>

输出为 11111011 </ code>-恰好是 -5 </ code>的2s补码。</ p>

所以在我看来,该值在内部真正是使用Two的补码,但格式为 未签名的 5 </ code>并在-</ code>之前。 </ p>

有人可以澄清吗?</ p>
</ div>

展开原文

原文

So computers use Two's complement to internally represent signed integers. I.e., -5 is represented as ^5 + 1 = "1111 1011".

However, trying to print the binary representation, e.g. the following code:

var i int8 = -5
fmt.Printf("%b", i)

Outputs -101. Not quite what I'd expect. Is the formatting different or is it not using Two's complement after all?

Interestingly, converting to an unsigned int results in the "correct" bit pattern:

var u uint8 = uint(i)
fmt.Printf("%b", u)

Output is 11111011 - exactly the 2s complement of -5.

So it seems to me the value is internally the really using Two's complement, but the formatting is printing the unsigned 5 and prepending a -.

Can somebody clarify this?

dounou9751
dounou9751 您有什么建议呢?
大约 4 年之前 回复
dsc80135
dsc80135 我认为您真的不希望通过玩用高级语言编写的数字格式化功能来理解2的补码。
大约 4 年之前 回复
du4010
du4010 好吧,我没说奇怪。我只是想了解2s补码,结果却不是我所期望的。
大约 4 年之前 回复
dourong4031
dourong4031 我不确定为什么有人会认为这个“怪异”。无论您使用什么数字基数,负数仍然是负数。如果您要求以8、12或16为基数,则我希望得到同样的结果。
大约 4 年之前 回复

2个回答

I believe the answer lies in how the fmt module formats binary numbers, rather than the internal format.

If you take a look at fmt.integer, one of the very first actions that the function does is to convert the negative signed integer to a positive one:

   165      negative := signedness == signed && a < 0
   166      if negative {
   167          a = -a
   168      }

There's then logic to append - in front of the string that's output here.

IOW -101 really is - appended to 5 in binary.

Note: fmt.integer is called from pp.fmtInt64 in print.go, itself called from pp.printArg in the same function.

Unsafe pointers must be used to correctly represent negative numbers in binary format.

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))
}

Output

11111011
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问