Go version
all so far
Output of go env
in your module/workspace:
n/a
What did you do?
Looked at/used math.Pi https://cs.opensource.google/go/go/+/refs/tags/go1.24.5:src/math/const.go;l=13
Pi = 3.14159265358979323846264338327950288419716939937510582097494459 // https://oeis.org/A000796
What did you see happen?
It has has 63 digits, so 209.2 ~210 bits of mantissa precision
What did you expect to see?
Should have 78+ plus digits or have all the digits mentioned on the link https://oeis.org/A000796/constant (105 digits)
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214
To get the 256+ bits the spec says
https://go.dev/ref/spec#Constants
Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed binary exponent of at least 16 bits.
(about 46 bits missing at the moment)
ps: Pi here is just an example, all the constants in that file have the same issue with truncated digits below the spec resolution
Comment From: ldemailly
Happy to send a CL if we agree this should be fixed (fix is easy, but someone somewhere might incorrectly rely on the curent values)
Comment From: randall77
It is not clear to me that this is worth fixing. Fixing this means someone can now depend on the 79th decimal digit, and in exchange we might break someone's code? Seems not worth the risk, even if the risk is really low.
Comment From: Oguidan
happy to send a CL is we agree this should be fixed (fix is easy, but someone somewhere surely incorrectly relies on the curent values)
Hi 👋🏽, what is CL
Comment From: Oguidan
It is not clear to me that this is worth fixing. Fixing this means someone can now depend on the 79th decimal digit, and in exchange we might break someone's code? Seems not worth the risk, even if the risk is really low.
I don't agree with you. That person should patch his code
Comment From: Jorropo
For context if we compare the ~209bits Pi value vs the proposed 256bits Pi value to calculate the volume of the observable universe the difference in results is ~= 7e-64
or 1.2% of the volume of the Moon which on the scale of the observable universe can be said to be small.
To summarize the discussion we had on discord I don't think we should change it, this is a public facing part of the API and we need a better justification than just because we can to change them.
Comment From: thepudds
Hi @ldemailly, I skimmed the discord conversation just now. It seems there was some confusion there if this is some type of spec violation. I tweaked the title here in an attempt to make it clearer, hopefully.
Comment From: ldemailly
Maybe using sqrt2 makes it clearer https://go.dev/play/p/mFhhjrEOIgq
package main
import (
"fmt"
"math"
)
const (
S2 = math.Sqrt2
SX = S2 * S2
S2p = 1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157
SXp = S2p * S2p
)
func main() {
fmt.Println(SX - 2)
fmt.Println(SXp - 2)
}
gives
5.683066758789326e-63
-7.735787349235918e-99
the error should be order of 1e-77, not 1e-63 for minimal spec required untyped float numbers (I still think it's violating the spec or the spirit of the spec that the provided constant have lower resolution than the minimal resolution specified for all go implementations - and again why 210, why not 70 bits then or 64 or 53+1 - it should be at least 256)
Comment From: ALTree
I don't think this is a spec violation.
The spec is just saying that conforming Go implementations are required to implement untyped constants arithmetic with internal precision of at least 256 bits; but this doesn't mean that any mathematical constant provided by the math
package has to be provided to 256 bits.
Suppose we wanted to expose some mathematical constant that is not know to 256 bits of precision... now what?
The math
package would be allowed to export pi = 3.1415
if it thinks it's enough precision to be useful, this has nothing to do with the required 256 bits that the compiler has to guarantee when doing arbitrary-precision arithmetic with untyped constants.
Comment From: ldemailly
Suppose we wanted to expose some mathematical constant that is not know to 256 bits of precision... now what?
Curious what that would be... but completely hypothetically... to whichever precision it is known (which for the links in the current source code for all the other constants is >= 256), so that doesn't contradict the current issue.
The math package would be allowed to export pi = 3.1415 if it thinks it's enough precision to be useful, this has nothing to do with the required 256 bits that the compiler has to guarantee when doing arbitrary-precision arithmetic with untyped constants.
Exactly... so what would you think is the most useful number of digits for the math package when the spec states that all implementation must support at least 256 bits and more isn't an error ?
a) >=256 [my choice] so 78 digits if we think there is a "cost" in pasting all 105 digits available from the referenced reference b) 210 (to repeat: why 210, why not 128 bits then or 64 or 53+1 or 2 (enough to get 1/5*5 == 1) c) some other value and why
Comment From: Jorropo
We do not need to come up with a good reason to keep it the way it is, not changing a public API is the default choice.
You need to come up with a good reason to do anything about it.