However I’ve noticed something unusual (at least I think so), It happens when using fmt and strconv (strconv in example) https://play.golang.org/p/0QF97RPCYB
My guess - I’ve misunderstood something. Perhaps I’m assuming the wrong max and min values. Or perhaps this is expected behaviour and I’m missing something.
If this is expected behaviour, why is it does strconv/fmt do this
Is there a way to change the func asString(f float) so that it works (works = nothing is printed because all strings match)?
Make sure you provide a way to easily figure out which test failed. Its also nicer when the expected and actual values are lined up so they are easier to compare.
To do this, I moved the comments you had for each test into a description field for the test. I also printed the expected and actual values on separate lines, using tab characters to line them up.
What you are missing is that float64 cannot represent every value. The next value after 9007199254740992 is 9007199254740994, not 9007199254740993. Use math.Nextafter to figure this out.
All of your failure cases make this same mistake (the number you specify can’t be represented exactly by float64). strconv.FormatFloat is behaving as specified:
The special precision -1 uses the smallest number of digits necessary such that ParseFloat will return f exactly.
So the highest number in Go I can reliably transform into a string is 9007199254740992?
And anything over 17 digits also cannot reliably be transformed into a string?
Or is there another numeric type I could consider - from the looks of the docs there’s not. https://golang.org/ref/spec#Numeric_types
I don’t have a use case for this - just interested
According to wikipedia, 15 digits is the safe number (with a decimal between any of them or without a decimal). With FormatFloat this assumes there are no trailing zeros after the decimal.
Great. Thanks for the response. I’ve marked as solved now.
I don’t think math.big removes same issue seen with Float64 when converting to string (https://play.golang.org/p/AapyD4vxTC) - it seems that there is a cap of 9007199254740992 on out the box numeric types printing as a sting without exponent in Go. However a few of the linked arbitrary precision decimal packages might.
FWIW, this restriction is not specific to Go. The floating-point format IEEE 754 is a universal format and used across programming languages and even directly supported by hardware.