首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >二的补码和fmt.Printf

二的补码和fmt.Printf
EN

Stack Overflow用户
提问于 2016-06-02 12:12:54
回答 3查看 3.6K关注 0票数 11

所以计算机使用二的补码在内部表示有符号的整数。即-5表示为^5 +1=“11111011”。

但是,尝试打印二进制表示,例如以下代码:

代码语言:javascript
运行
复制
var i int8 = -5
fmt.Printf("%b", i)

输出-101。和我想的不太一样。是格式不同,还是不使用二的补码?

有趣的是,转换为无符号int会产生“正确”的位模式:

代码语言:javascript
运行
复制
var u uint8 = uint(i)
fmt.Printf("%b", u)

输出是11111011 --恰好是-5的2补码。

所以在我看来,它的值在内部实际上是使用2的补码,但是格式是打印无符号的5并在前面加上一个-

有人能澄清这一点吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-02 12:46:14

我相信答案在于fmt模块如何格式化二进制数,而不是内部格式。

如果您查看一下fmt.integer,该函数执行的第一个操作之一就是将负号整数转换为正整数:

代码语言:javascript
运行
复制
   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调用的。

票数 10
EN

Stack Overflow用户

发布于 2021-07-07 06:18:59

下面是一种不使用unsafe的方法

代码语言:javascript
运行
复制
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,但如果您有一个正整数,并且想要修剪前导零,那么上面的方法会更好。

https://golang.org/pkg/math/bits#RotateLeft

票数 0
EN

Stack Overflow用户

发布于 2019-04-24 03:14:07

必须使用不安全指针以二进制格式正确表示负数。

代码语言:javascript
运行
复制
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))
}

输出

代码语言:javascript
运行
复制
11111011
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37582550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档