-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Pretty print isn't pretty for floats #29472
Comments
1.2999999999999999 != 1.3. Pretty printing should not be inaccurate by default. However, we've long wanted a mode that prints the shortest exact literal, see #24612 for some discussion. The difference to the default behavior would be that it would use exponential notation when that gives a shorter result. This mode should probably accept a precision Aside:
Wouldn't serialization libraries want accuracy more than pleasing human readers? |
Thank you for conception.
Not by humans. But problem becoming little deeper... I have some Lua code, which contains parameters that numeric constants. I used to pure Lua to JSON serializer which calls Lua's #24612 doesn't provide a twin for |
No, AFAIK there hasn't been any activity on a |
I've found better example: fn main() {
let mut x = 0.1;
for z in (1..100) {
x = x + 0.01;
println!("{}", x);
}
} it prints: 0.11
0.12
0.13
0.14
0.15000000000000002
0.16000000000000003
0.17000000000000004
0.18000000000000005
0.19000000000000006
0.20000000000000007
0.21000000000000008
0.22000000000000008 That's really terrible print ) |
This is an example of floating point arithmetic being inaccurate. The number really is closer to
Besides, I do not buy that other languages do round by default. Here's Java, JavaScript, Python, Ruby giving identical or very similar output. Either Also, changing the default is tricky because lots of programs rely on the exact current behavior. Rounding the output might not break any programs (though it will make some of them less accurate, if they read the output back in), but as explained above I am opposed to that anyway. |
I think you are right, |
I absolutely agree with you that there should be a formatting operator that is prettier and can also round to N decimal digits while remaining pretty. I just don't want it to round by default. |
cc me |
If you want to error free load/store floating point via text files and target multiple languages...use hexadecimal. Using decimal is a recipe for pain. |
It's true that decimal representation of binary floats has many downsides, but unfortunately it is also very convenient for humans. Decimal output must exist, might as well make it as pretty as possible while remaining accurate — to say nothing of output for end users that is never read back in. And the really hard part of the implementation is already solved, loading and storing floating point number is already correct in Rust today. It may have to round when first reading decimal input, but every subsequent load-store cycle preserves the bits exactly. |
@rkruppe I had assumed that the suggestion to use hexadecimal was a response to the scenario given above where one is trying to serialize data between Lua and Rust. (But then again, it was unclear whom @roquendm 's comment was actually directed at... the "and target multiple languages" part was what made me think the text was targetted at @deniskolodin ) |
The discussion on #24612 did (in a comment) mention how we might want to make But its not clear how far we would actually want to go with this. It would probably better to allocate a separate format modifier for this purpose, e.g. |
Since |
Indeed my comment was "if one wants to (as simply as possible) be bit-exact across all languages which might read/write the data in a text based format" then use hex floats, |
Nominating to discuss:
I'm not a huge fan of 1, but 2 doesn't seem crazy... although 3 and/or people just using e.g. |
I see in the doc that: What about to use println!("{:-}", 1.2999999999999999);
// 1.3
println!("{:-?}", 1.2999999999999999);
// 1.3 |
I'm not sure what you're saying here, can't the @deniskolodin Another thing that bugs me about a direct
This is pretty much what C's NB: I would also prefer ordinary |
Libs team consensus: any of the changes being discussed here should go through the RFC process. The team would be wiling to consider an RFC for any of the options @huonw mentioned, but would be particularly keen for either option 2 or 3. |
The following code:
prints:
C behaviour:
prints:
1.3
With Rust everything works like f, but not like g.
Is that really no way to get behaviour like g option of
printf
?It's highly important feature for serialization libs.
rustc 1.6.0-nightly (8ca0acc 2015-10-28)
The text was updated successfully, but these errors were encountered: