-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fmt: floating numbers are rounded inconsistently for "%.Nf" where N > 1 #21091
Comments
because Closing this, since it's not a bug. |
Thanks for the explanation. I, however, would still argue that this is a bug, even if the current behavior aligns with internal implementation quirks. The problem is that the final output is inconsistent from the end user's perspective, and this is definitely not a behavior one would deliberately want to have when formatting numbers. https://golang.org/pkg/fmt/ doesn't provide any documentation on this behavior, either (and if this is considered a non-issue, it deserves to be at least documented). |
Go uses IEEE floating point, and this is how IEEE floating point works. What you are suggesting is something more like decimal floating point. See https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html for detail on IEEE floats. |
I guess the 'decimal floating point' is what people would expect from a formatting function, no? I can totally understand the logic from the developer's point of view ("we stick to IEEE spec with all its side effects related to rounding"), but what is good for the developer is not necessarily good for the consumer, and formatting is a user-facing aspect. I can't imagine myself saying something like "this is not a bug, this is a feature of IEEE floats; deal with it" to the user of my app. So if I want to implement the formatting the way users would expect it, I, as a developer, would like to at least be warned about these quirks in the documentation of the fmt package, and make my decision on whether to implement workarounds. It would be good to get this issue a better exposure to see what others think about this. Maybe I'm just a special snowflake and everybody else expects the formatting to work the way it works now. |
You can argue it both ways. If Go behaves differently than C, a different set of people will be surprised. It would certainly be reasonable to solicit more opinions. On the other hand, this clearly can not change before Go 2. |
@iafan I guess I don't actually understand what you are suggesting. You are proposing that we keep the standard IEEE754 representation, but change the way we print floats to align more with that the end user expectations. How are we supposed to do that? Consider:
Right now, we print:
If we were to follow your suggestion, we would print:
This is not a reasonable expectation, because the two numbers have the exact same IEEE754 representation. How are we supposed to distinguish between the case where the user wanted If the current behaviour is problematic for you, the best solution, as Ian suggested, is to use a decimal library not built on IEEE754, one that can handle and format decimal numbers the way humans expect them. |
@ALTree yes, I was suggesting to adjust the formatting only without changing any internals. And I believe it is possible to do so. Here's my (probably naive) Having said that, @ianlancetaylor has a good point: some existing users may rely on the current formatting behavior even if it's not mathematically correct. So probably two formatting implementations could co-exist for backward compatibility and default to the old behavior (and differences between them should be documented to avoid surprises). |
@ALTree note that I'm not talking about cases with the precision overflow: fmt.Printf("%.2f\n", 1.005)
fmt.Printf("%.2f\n", 1.00499999999999998) is essentially the same as fmt.Printf("%.2f\n", 1.005)
fmt.Printf("%.2f\n", 1.005) and I would expect it to produce:
|
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go1.8.3 darwin/amd64 (but also reproducible in the official playground)
What did you do?
Consider the following example that fully explains the issue:
The same code in the playground
What did you expect to see?
I would expect proper rounding of the fractional part regardless of the integer part value.
What did you see instead?
Inconsistent rounding as depicted in the sample code.
The text was updated successfully, but these errors were encountered: