go - 位操作使有符号整数变为无符号
问题描述
计算机使用二进制补码来存储整数。比如说,对于 int32 签名,0xFFFFFFFF 代表“-1”。根据这个理论,用 C 语言编写这样的代码将有符号整数初始化为 -1 并不难;
int a = 0xffffffff;
printf("%d\n", a);
显然,结果是-1
。
但是,在 Go 中,相同的逻辑转储不同。
a := int(0xffffffff)
fmt.Printf("%d\n", c)
代码片段打印4294967295
uint32 类型可以容纳的最大数量。即使我c
明确地投入fmt.Printf("%d\n", int(c))
,结果仍然是一样的。
当对有符号整数也施加一些位操作时,也会发生同样的问题,使有符号变为无符号。
那么,在这种情况下,Go 会发生什么?
解决方案
这里的问题是大小int
不固定,它取决于平台。它可能是 32 位或 64 位。在后一种情况下,分配0xffffffff
给它等同于分配4294967295
给它,这就是您看到的打印内容。
现在,如果您将该值转换为int32
(32 位),您将获得-1
:
a := int(0xffffffff)
fmt.Printf("%d\n", a)
b := int32(a)
fmt.Printf("%d\n", b)
这将输出(在Go Playgroung上尝试):
4294967295
-1
另请注意,在 Go 中,无法0xffffffff
直接分配 typeint32
的值,因为该值会溢出;创建具有非法值的类型化常量(例如int32(0xffffffff)
. 规格:常数:
类型化常量的值必须始终可以由常量类型的值准确表示。
所以这给出了一个编译时错误:
var c int32 = 0xffffffff // constant 4294967295 overflows int32
但你可以简单地做:
var c int32 = -1
你也可以这样做:
var c = ^int32(0) // -1
推荐阅读
- sparql - 如何列出自定义 Wikibase 实例上的所有属性
- moodle - 根据用户角色创建 CSS 类
- java - java中的arraylist,打印出所有数据
- youtube-api - 使用 Youtube Data API 使我的视频在上传时成为私密视频
- c# - 输入字符串的格式不正确 - 传递 NULL 值时
- html - WebStorm - 实时模板 - Twig + Html 不起作用
- reactjs - 如何删除 React Navigation 5 中每个选项卡屏幕的标题?
- kubernetes - 微服务 API 网关和 Identity Server 4 kubernates
- php - localhost:xxxx 数据库连接更改为 TCP/IP?
- reactjs - React Hook 函数 useEffect