Repository navigation
lib: don't truncate large floats in config_write - #307
Merged
Merged
Conversation
value_buf only has room for a 64-bit binary integer, and %f never uses an exponent, so large floats were cut off at 61 characters and written as a different value. Give the float case a buffer that fits every integer digit of DBL_MAX.
hyperrealm
reviewed
Nov 5, 2026
| { | ||
| /* %f never switches to an exponent, so this must hold every integer | ||
| digit of DBL_MAX; only fractional digits may be truncated. */ | ||
| char float_buf[DBL_MAX_10_EXP + 64]; |
Owner
There was a problem hiding this comment.
It would be better to just make value_buf big enough for any type of value instead of having a separate buffer here just for floats.
Contributor
Author
There was a problem hiding this comment.
Agreed, that's simpler. I removed float_buf and made value_buf large enough for both 64-bit binary output and floats printed with %f, so floats use value_buf again. All tests still pass, including the new WriteLargeFloat test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
config_write formats floats into value_buf, which only has room for a 64-bit binary integer. %f never switches to an exponent, so large values get cut off at 61 characters, leaving a different number in the file. x = 1e300 reads back as about 1e60, with no error.
The float case now uses its own buffer with room for every integer digit of DBL_MAX.
I added a WriteLargeFloat test that writes and rereads values from 1e60 up to DBL_MAX. It fails on master, and the suite passes with the fix. I also compared old and new output on 300k random doubles under ASan and UBSan: nothing below 1e55 changed.
Very small values such as 1e-300 still come out as 0.0 unless scientific notation is enabled. I left that separate issue unchanged.