Go 具有任意大小和精度的无类型精确数值常量。这spec requires https://golang.org/ref/spec#Constants所有编译器都支持至少 256 位的整数,以及至少 272 位的浮点数(尾数为 256 位,指数为 16 位)。因此,编译器需要忠实、准确地表示如下表达式:
const (
PI = 3.1415926535897932384626433832795028841971
Prime256 = 84028154888444252871881479176271707868370175636848156449781508641811196133203
)
这很有趣......但我找不到任何方法来实际使用任何超过 64 位具体类型最大精度的常量int64
, uint64
, float64
, complex128
(这只是一对float64
值)。甚至标准库大数类型 https://golang.org/pkg/math/big/ big.Int
and big.Float
不能从大型数字常量初始化——它们必须从字符串常量或其他表达式反序列化。
底层机制相当明显:常量仅在编译时存在,并且必须强制为可在运行时表示的某个值才能在运行时使用。它们是仅存在于代码和编译期间的语言构造。您无法在运行时检索常量的原始值;它不存储在编译后的程序本身的某个地址处。
所以问题依然存在:当大量常量无法在实践中使用时,为什么该语言要如此强调支持它们呢?
TLDR;Go 的任意精度常量使您可以使用“真实”数字而不是“盒装”数字,因此可以缓解溢出、下溢、无穷大极端情况等“伪影”。您可以以更高的精度进行工作,并且只需将结果转换为有限精度,从而减轻中间误差的影响。
Go 博客:常量: https://blog.golang.org/constants(强调是我回答你的问题)
数字常量存在于任意精度的数字空间中;它们只是普通数字。但是,当将它们分配给变量时,该值必须能够适合目标。我们可以声明一个非常大的值的常量:
const Huge = 1e1000
——毕竟,这只是一个数字——但我们无法分配它,甚至无法打印它。该语句甚至无法编译:
fmt.Println(Huge)
错误是“constant 1.00000e+1000 溢出 float64”,这是正确的。But Huge
可能有用:我们可以在具有其他常量的表达式中使用它,并且如果结果可以在 a 的范围内表示,则可以使用这些表达式的值float64
.该声明,
fmt.Println(Huge / 1e999)
prints 10
,正如人们所期望的那样。
以相关的方式,浮点常量可能具有非常高的精度,因此涉及它们的算术更加准确。中定义的常量math https://golang.org/pkg/math包中给出的数字远多于可用的数字float64
。这是定义math.Pi
:
Pi = 3.14159265358979323846264338327950288419716939937510582097494459
当将该值分配给变量时,一些精度将会丢失;该作业将创建float64
(or float32
) 最接近高精度值的值。这个片段
pi := math.Pi
fmt.Println(pi)
prints 3.141592653589793
.
有如此多的可用数字意味着像这样的计算Pi/2
或者其他更复杂的计算可以在结果被分配之前具有更高的精度,使得涉及常量的计算更容易编写而不会损失精度。这也意味着不存在浮点极端情况,如无穷大、软下溢和NaN
s 出现在常量表达式中。(除以常量零是一个编译时错误,当一切都是数字时,就不存在“不是数字”这样的事情。)
参见相关:Go 如何对常量进行算术运算? https://stackoverflow.com/questions/38982278/how-does-go-perform-arithmetic-on-constants/38982889#38982889
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)