Go中任意精度常数的目的是什么? [英] What is the purpose of arbitrary precision constants in Go?

查看:77
本文介绍了Go中任意精度常数的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Go具有任意大小和精度的无类型精确数字常量。 规范需要 所有编译器都必须支持至少256位的整数,并且至少浮动到272位(尾数为256位,指数为16位)。因此,要求编译器忠实,准确地表示这样的表达式:

Go features untyped exact numeric constants with arbitrary size and precision. The spec requires all compilers to support integers to at least 256 bits, and floats to at least 272 bits (256 bits for the mantissa and 16 bits for the exponent). So compilers are required to faithfully and exactly represent expressions like this:

const (
    PI       = 3.1415926535897932384626433832795028841971
    Prime256 = 84028154888444252871881479176271707868370175636848156449781508641811196133203
)

这很有趣...但是我找不到任何方法来实际使用任何超过64位具体类型 int64 uint64 float64 complex128 (只是一对 float64 值)。甚至标准库大数字类型 big.Int big.Float 无法从大型数字常量初始化,而必须从字符串常量或其他表达式反序列化。

This is interesting...and yet I cannot find any way to actually use any such constant that exceeds the maximum precision of the 64 bit concrete types int64, uint64, float64, complex128 (which is just a pair of float64 values). Even the standard library big number types big.Int and big.Float cannot be initialized from large numeric constants -- they must instead be deserialized from string constants or other expressions.

基本机制很明显:常量仅在编译时存在,并且必须强制为某个可在运行时表示的值才能在运行时使用。它们是仅在代码中和编译期间存在的语言构造。您无法在运行时检索常量的原始值;它不存储在已编译程序本身的某个地址中。

The underlying mechanics are fairly obvious: the constants exist only at compile time, and must be coerced to some value representable at runtime to be used at runtime. They are a language construct that exists only in code and during compilation. You cannot retrieve the raw value of a constant at runtime; it is is not stored at some address in the compiled program itself.

所以问题仍然存在:为什么语言在不能实际使用时为什么会支持巨大的常量呢?

推荐答案

TLDR; Go的任意精度常量使您可以使用 real函数。数字,而不是带有框的数字数字,因此工件像溢流,下溢,无穷大拐角情况。您可以以更高的精度工作,并且只需要将结果转换为有限精度,就可以减轻中间错误的影响。

TLDR; Go's arbitrary precision constants give you the possibility to work with "real" numbers and not with "boxed" numbers, so "artifacts" like overflow, underflow, infinity corner cases are relieved. You have the possibility to work with higher precision, and only the result have to be converted to limited-precision, mitigating the effect of intermediate errors.

The Go博客:常量:(强调的是我在回答您的问题)

The Go Blog: Constants: (emphasizes are mine answering your question)


数字常数存在于任意精度的数字空间中。它们只是常规数。但是,当将它们分配给变量时,该值必须能够适合目标。我们可以声明一个非常大的常量:

Numeric constants live in an arbitrary-precision numeric space; they are just regular numbers. But when they are assigned to a variable the value must be able to fit in the destination. We can declare a constant with a very large value:

const Huge = 1e1000

-毕竟这只是一个数字-但我们无法分配它甚至无法打印它。该语句甚至不会编译:

—that's just a number, after all—but we can't assign it or even print it. This statement won't even compile:

fmt.Println(Huge)

错误是,常数1.00000e + 1000溢出float64,这是正确的。 但是巨大可能有用:我们可以在具有其他常量的表达式中使用它,并且如果结果可以在 float64 语句,

The error is, "constant 1.00000e+1000 overflows float64", which is true. But Huge might be useful: we can use it in expressions with other constants and use the value of those expressions if the result can be represented in the range of a float64. The statement,

fmt.Println(Huge / 1e999)

打印出 10 ,就像人们期望的那样。

prints 10, as one would expect.

以一种相关的方式,浮点常量可能具有非常高的精度,因此涉及它们的算术更加准确。数学软件包所提供的位数比 float64 中可用的位数多得多。这是 math.Pi 的定义:

In a related way, floating-point constants may have very high precision, so that arithmetic involving them is more accurate. The constants defined in the math package are given with many more digits than are available in a float64. Here is the definition of math.Pi:

Pi    = 3.14159265358979323846264338327950288419716939937510582097494459

将该值分配给变量时,某些精度将丢失; 分配将创建最接近高精度值的 float64 (或 float32 )值。此代码段

When that value is assigned to a variable, some of the precision will be lost; the assignment will create the float64 (or float32) value closest to the high-precision value. This snippet

pi := math.Pi
fmt.Println(pi)

打印 3.141592653589793

可用数字太多意味着像 Pi / 2 之类的计算或其他更复杂的求值方法可以在分配结果之前具有更高的精度,从而使包含常量的计算更容易编写而不会损失精度。这也意味着在任何情况下都不会在常量表达式中出现诸如无穷大,软下溢和 NaN 之类的浮点拐角情况。(除以常数零是编译时错误,当所有内容都是数字时,就没有不是数字之类的东西。)

Having so many digits available means that calculations like Pi/2 or other more intricate evaluations can carry more precision until the result is assigned, making calculations involving constants easier to write without losing precision. It also means that there is no occasion in which the floating-point corner cases like infinities, soft underflows, and NaNs arise in constant expressions. (Division by a constant zero is a compile-time error, and when everything is a number there's no such thing as "not a number".)

查看相关内容: Go如何对常量执行算术运算?

这篇关于Go中任意精度常数的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆