位运算使有符号整数变为无符号

3

计算机使用二进制补码来存储整数。例如,对于int32有符号整型,0xFFFFFFFF表示“-1”。根据这个理论,在C语言中编写将有符号整数初始化为-1的代码并不难;

int a = 0xffffffff;
printf("%d\n", a);

显然,结果是-1

然而,在Go语言中,相同的逻辑输出不同。

a := int(0xffffffff)
fmt.Printf("%d\n", c)

该代码片段打印出 4294967295,这是 uint32 类型可容纳的最大数字。即使我在 fmt.Printf("%d\n", int(c)) 中对 c 进行了显式转换,结果仍然相同。
当对有符号整数执行一些位运算时,也会发生同样的问题,使有符号整数变成无符号整数。
那么,在这种情况下,Go 会发生什么?
1个回答

3
这里的问题在于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 Playground上尝试):
4294967295
-1

请注意,在Go语言中,不可能直接将值为0xffffffff的数值赋给类型为int32的变量,因为该值会溢出;也不能创建具有非法值(例如int32(0xffffffff))的已命名常量。规范:常量:

已命名常量的值必须始终可以由该常量类型的值准确表示

因此,这会导致编译时错误:

var c int32 = 0xffffffff // constant 4294967295 overflows int32

但是你可以简单地执行:

var c int32 = -1

您也可以执行以下操作:

var c = ^int32(0) // -1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接