我在数学/大库中发现了一些看起来很奇怪的代码,但不明白它是如何工作的。我已将常量提取到一个示例中:
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
最大值为2147483647
int64
最大值为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 编译器的计算对于常量表达式和其他表达式是否不同