Skip to content
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

Misc fixes #173

Merged
merged 2 commits into from
Oct 9, 2023
Merged

Misc fixes #173

merged 2 commits into from
Oct 9, 2023

Conversation

nbd168
Copy link
Contributor

@nbd168 nbd168 commented Sep 29, 2023

Two compile error fixes for macOS, and a fix for preserving the double type when generating JSON.

types.c Outdated
ucv_stringbuf_printf(pb, "%.14g", d);
else {
size_t len = ucv_stringbuf_printf(pb, "%.14g", d);
if (json && !strchr(pb->buf + pb->bpos - len, '.'))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this feels slightly unelegant. What about this:

...
else if (json && trunc(d) == d)
    ucv_stringbuf_printf(pb, "%.1f", d);
else 
    ucv_stringbuf_printf(pb, "%.14g", d);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about doing it this way too, but I read in a few places that this can be prone to corner cases caused by weird floating point rounding issue. I think checking the output of sprintf is more reliable.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be prone to corner cases caused by weird floating point rounding issue

Hm, can you provide some links for this? My research so far seems to indicate that trunc(x) == x is indeed the way to go, but maybe I overlooked something.

The problem with the "scan backwards for a decimal point and append .0 if none found" approach is that it will fail if the %g format decides to yield an exponent form, e.g. we don't want to turn 1e100 into 1e100.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I can't find the original link anymore. I took a look at this from another angle and checked how existing JSON libraries are handling this issue. I looked at json-c, jansson and yajl, and they all use the scan-for-decimal-point approach. The code is rather different in each one, so I don't believe it was copied/cargo-culted between implementations. Would you accept my patch if I keep the approach, but fix the exponent form case?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a fix based on your suggestion and including a testcase covering this corner case. Could you rebase this PR against master so that I can merge the remainder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

jow- added a commit that referenced this pull request Oct 9, 2023
The `%g` printf format used for serializing double values into strings
will not include any decimal place if the value happens to be integral,
leading to an unwanted double to integer conversion when serializing
and subsequently deserializing an integral double value as JSON.

Solve this issue by checking the serialized string result for a decimal
point or exponential notation and appending `.0` if neither is found.

Ref: #173
Suggested-by: Felix Fietkau <[email protected]>
Signed-off-by: Jo-Philipp Wich <[email protected]>
nbd168 added 2 commits October 9, 2023 15:56
Accept char * const *, cast internally. Fixes a compile error

Signed-off-by: Felix Fietkau <[email protected]>
@jow- jow- merged commit 9369b38 into jow-:master Oct 9, 2023
@jow-
Copy link
Owner

jow- commented Oct 9, 2023

Merged, thanks for your patience :)

@nbd168 nbd168 deleted the misc-fixes branch April 7, 2024 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants