Skip to content

Bug fix: decimalPlaces will not return correctly for a large double value #772

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

Closed
wants to merge 3 commits into from

Conversation

Binyang2014
Copy link

When use stringWriterBuilder to write a really large double value, the program may return an incorrect value if we set the precisionType to decimalPlaces. The root cause for this issue is we not check if we convert double to string successfully (sometime the is buffer will be too small to contain the whole string). For this case, I will use significantDigits type instead, and set the precision to 17.

…value, the program may return an incorrect value if we set the precisionType to decimalPlaces. The root cause for this issue is we not check if we convert double to string successfully (sometime the is buffer will be too small to contain the whole string). For this case, I will use significantDigits type instead, and set the precision to 17.
@cdunn2001
Copy link
Contributor

That's a great catch! However, shouldn't we also increase the buffer size so the if-antecedent is never true? In fact, if we make the buffer is big enough, can we turn the consequent into an exception for the case which should never occur?

@Binyang2014
Copy link
Author

Thanks Christopher, but I think we can't know the buffer size until we call snprintf function. I believe there is no max length for the double value which use fixed decimal. So if we want to make the buffer big enough, we need to alloc the buffer dynamically. In this way, we need to call snprintf first to get the correct buffer size, then alloc the buffer.

Since we already set the max precision for double value to 17. For a fixed decimal value, if it exceed the buffer size, I think we can use significant decimal type instead.

@BillyGoto
Copy link

BillyGoto commented May 10, 2018 via email

@@ -165,7 +166,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
}
}
assert(len >= 0);
assert(len >= 0 && len < sizeof(buffer));
Copy link
Contributor

Choose a reason for hiding this comment

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

This assert happens way too late. We already used len as a range limit above in the calls to fixNumericLocale etc.
Also the "%%.%ug" 2-stage snprintf is wasteful. We can just use .* precision.

I would like to refactor this function before changing it. I'll send a PR.

Copy link
Author

@Binyang2014 Binyang2014 May 12, 2018

Choose a reason for hiding this comment

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

Thanks Billy, I will wait for your code refactor.

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.

4 participants