为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不能将 int64 的最小值存储到 uint64 中?

为什么不能将 int64 的最小值存储到 uint64 中?

Go
开心每一天1111 2022-10-10 15:54:47
理论上 int64 适合 uint64,当然它们的数值会有所不同,因为第一位是为 int64 上的符号保留的,但是为什么我不能进行这种转换呢?对我来说似乎有效import (    "fmt"    "math")func main() {    var randomNum uint64 = math.MinInt64    fmt.Println(randomNum)}产生错误constant -9223372036854775808 overflows uint64从技术上讲,这math.MinInt64是-9223372036854775808一个适合 63 位加号的数字。我主要研究这个,因为我想转换8 bytes回具有正确符号的 int64,但到目前为止我只看到返回的函数uint64binary.LittleEndian.Uint64(bytesArrays[0:8])
查看完整描述

3 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

这种“转换”不起作用的原因是因为您的程序中没有转换。赋值不会隐式执行转换(接口类型除外)。

请参阅管理常量值分配的可分配性规则

如果以下条件之一适用,则值 x 可分配给 T 类型的变量(“x 可分配给 T”):

  • x 的类型与 T 相同。

  • ...

  • x 是一个无类型的常量,可以用 T 类型的值表示。

在这种情况下,math.MinInt64是一个无类型常量,但它不能用 type 的值表示uint64,因为它是这样定义的:

uint64 所有无符号 64 位整数的集合(0 到 18446744073709551615)

负 64 位整数和无符号 64 位整数之间的转换是可能的,但您需要真正的转换。然而,由于熟悉的规则,您仍然不能直接转换常量值:

如果 x 可以由 T 的值表示,则常数值 x 可以转换为类型 T。

所以,正确的方法是先将数字赋给一个非常量值:

x := int64(math.MinInt64)

y := uint64(x)

fmt.Println(y)

游乐场链接


查看完整回答
反对 回复 2022-10-10
?
aluckdog

TA贡献1847条经验 获得超7个赞

int64 适合 uint64,但这不是问题中的代码所做的。该代码将常量 math.MinInt64 分配给 uint64 变量randomNum。编译器报告错误,因为该常量不能用 uint64表示。


首先分配给一个变量,这样常量的规则就不会适用:


x := int64(math.MinInt64)

var randomNum = uint64(x)

fmt.Println(randomNum)


查看完整回答
反对 回复 2022-10-10
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

谁说你不能?好的,编译器是这么说的。但是编译器意味着您不能将 -9223372036854775808放入uint64变量中,这是正确的;您需要将位模式作为 int64 表示 -9223372036854775808,但表示将被视为 uint64的值uint64

var randomNum uint64 = math.MinInt64 + math.MaxUint64 + 1

效果很好——或者当然可以做GastroHealth 展示的事情。

我主要研究这个,因为我想将 [8] 字节转换回具有正确符号的 int64,但到目前为止,我只看到返回 uint64 的函数(例如binary.LittleEndian.Uint64)。

我们做的很明显:

signed := int64(v ^ 0x8000000000000000 - 0x8000000000000000)

(嗯,看过几次就很明显了。)

在这里查看一个完整的示例(我使用大端,我更喜欢它供人类使用)。请注意,您可以在signed := int64(v)这里执行;翻转和减法技巧非常适合作为您还没有变量的表达式。


查看完整回答
反对 回复 2022-10-10
  • 3 回答
  • 0 关注
  • 193 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信