栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么在golang中没有左移64位溢出?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么在golang中没有左移64位溢出?

当你写

1<<64

1
上面没有一个
int64
。这是一个 常量常量 。根据语言规格:

常量表达式总是精确地求值;中间值和常量本身可能需要比该语言中任何预声明类型支持的精度大得多的精度。

因此,常量文字会在编译时进行评估,因为它不是语言实现的特定类型,所以它可能非常大。

下面实际上会给出一个溢出错误:

var i int64i = 1<<65 - 1

因为现在常量文字表达式求值的值大于

int64
可以包含的值。

在此处阅读有关此内容的更多信息。

要知道您的示例代码为何适用

i = 65
,请参考Golang
规范中的以下规范:

移位表达式中的右操作数必须具有无符号整数类型,或者是可以转换为无符号整数类型的无类型常量。如果 非恒定移位表达式
左操作数是未类型化的常数,则首先将其转换为假定移位表达式被其左操作数单独替换时所假定的类型

上面的膨胀部分与您的代码有关。考虑下面的代码:

a := 66var j uint64 = 1<<uint64(a) - 1

在移位运算符中,右操作数是 一个非恒定的表达式 。因此整个移位操作成为 非恒定移位表达式 。因此,如上所述,将左操作数

1
转换为
uint64

现在,已在上

uint64(1)
进行了平移,可以使用所需的任意
<<
多个位置进行平移。您可以将其移位到64位以上,并且实现将很容易地允许它。但是在这种情况下,保存
uint64(1)
上述内容的内存将包含全零。

请注意,根据语言规范,此行为与溢出并不相同。同样,只要正确的运算符不是常量表达式,语言限制就可以进行任意多的移位。因此,例如,这将起作用:

a := 6666var j uint64 = 1<<uint64(a) - 1 // non-constant shift expression

这样想吧。较早时,未输入

1
。它具有任意精度(取决于实现),并且正在返回整数(所有位)。现在,由于它是a
uint64
,因此仅考虑了前64位。

这仍然会导致溢出,因为左操作数

1
是untypes,并且可能包含大量位,对于a返回的值太大
uint64

var j uint64 = 1<<uint64(66) - 1 // overflow. Note that uint64(64)fmt.Println(j)        // is typed, but it's still a constant


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/633222.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号