What is the purpose of arbitrary precision constants in Go?

后端 未结 1 870
渐次进展
渐次进展 2021-01-29 07:11

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 2

相关标签:
1条回答
  • 2021-01-29 07:53

    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 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)
    

    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)
    

    prints 10, as one would expect.

    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
    

    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)
    

    prints 3.141592653589793.

    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".)

    See related: How does Go perform arithmetic on constants?

    0 讨论(0)
提交回复
热议问题