以下代码的问题:
var x uint64 = 18446744073709551615
var y int64 = int64(x)
就是y
这样-1
。在不丢失信息的情况下,在这两种数字类型之间进行转换以使用编码器和解码器的唯一方法是什么?
buff bytes.Buffer
Encoder(buff).encode(x)
Decoder(buff).decode(y)
请注意,在您的典型情况下,我没有尝试直接进行数字转换。我更关心维护随机数生成器的统计特性。
您的转换不会丢失转换中的任何信息。所有位都将保持不变。就是这样:
uint64(18446744073709551615) = 0xFFFFFFFFFFFFFFFF
int64(-1) = 0xFFFFFFFFFFFFFFFF
尝试:
var x uint64 = 18446744073709551615 - 3
你将拥有y = -4
.
例如:操场
var x uint64 = 18446744073709551615 - 3
var y int64 = int64(x)
fmt.Printf("%b\n", x)
fmt.Printf("%b or %d\n", y, y)
输出:
1111111111111111111111111111111111111111111111111111111111111100
-100 or -4
看到 -1 将与以 32 位运行的进程一致。
参见例如Go1.1 发行说明(其中介绍了uint64
)
x := ^uint32(0) // x is 0xffffffff
i := int(x) // i is -1 on 32-bit systems, 0xffffffff on 64-bit
fmt.Println(i)
使用fmt.Printf("%b\n", y)
可以帮助查看发生了什么(请参阅ANisus的回答)
事实证明,OP wheaties确认(在评论中)它最初是以 32 位运行的(因此是这个答案),但随后意识到18446744073709551615
是0xffffffffffffffff
(-1)无论如何:见ANisus答案;
uint64 和 int64 类型都可以表示 2^64 个离散整数值。
两者的区别在于 uint64 只保存正整数(0 到 2^64-1),而 int64 保存负整数和正整数,使用 1 位来保存符号(-2^63 到 2^63-1) .
正如其他人所说,如果您的生成器正在生成0xffffffffffffffff
,则 uint64 会将其表示为原始整数 (18,446,744,073,709,551,615),而 int64 将解释两者的补码并返回 -1。