数学/大:常18446744073709551616溢出 int?



我在数学/大库中发现了一些看起来很奇怪的代码,但不明白它是如何工作的。我已将常量提取到一个示例中:

package main
import (
"fmt"
"math/bits"
)
const (
_S = _W / 8 // word size in bytes
_W = bits.UintSize // word size in bits
_B = 1 << _W       // digit base
_M = _B - 1        // digit mask
)
func main() {
fmt.Println(_S, _W, _B, _M)
}

返回错误:

bug/example.go:17:13: constant 18446744073709551616 overflows int
bug/example.go:17:13: constant 18446744073709551615 overflows int

需要明确的是,我理解为什么这段代码不起作用。我感兴趣的是知道为什么在标准库中使用此常量时不会发生此错误?

我认为它可能被延迟评估(即_B - 1),但我可以看到它确实用于测试。那么这里会用什么值呢?

"常量18446744073709551616溢出 int?">-- 是的。

int取决于体系结构至少为 32 位。int32最大值为2147483647int64最大值为9223372036854775807两者都不够大,无法容纳18446744073709551615

<小时 />

https://golang.org/ref/spec#Constants

数值常量表示任意精度的精确值,并执行 不溢出。因此,没有常量表示 IEEE-754 负零、无穷大和非数字值。

常量

可以通过常量声明显式赋予类型,或者 转换,或在变量声明或 赋值或作为表达式中的操作数。这是一个错误,如果 常量值不能表示为相应的值 类型。

在您的情况下,根据使用它的表达式,常量值被赋予类型int,并且由于它不能由该类型表示,因此会导致错误。


如果您希望编译代码,您可以将常量转换为float64(在_M的情况下为uint)。

package main
import (
"fmt"
"math/bits"
)
const (
_S = _W / 8 // word size in bytes
_W = bits.UintSize // word size in bits
_B = 1 << _W       // digit base
_M = _B - 1        // digit mask
)
func main() {
fmt.Println(_S, _W, float64(_B), uint(_M))
}

https://play.golang.org/p/AVT5FPHinT3


有关更多信息,请参阅: Go 编译器的计算对于常量表达式和其他表达式是否不同

最新更新