Fix a precision bug of valueToString, prevent to give an error result… (#1246)

* Fix a precision bug of valueToString, prevent to give an error result on input of wanted precision 0 and a double value which end of zero before decimal point ,such as 1230.01,12300.1;
Add test cases for double valueToString with precision 0;

* Delete a test case with platform differences in the previous commit

* Fix clang-format.

* Fix clang-format!

Co-authored-by: lilei <dlilei@126.com>
This commit is contained in:
Lei 2020-12-16 03:08:05 +08:00 committed by GitHub
parent 8954092f0a
commit 940982438d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 8 deletions

2
.gitignore vendored
View File

@ -10,6 +10,7 @@
/libs/ /libs/
/doc/doxyfile /doc/doxyfile
/dist/ /dist/
/.cache/
# MSVC project files: # MSVC project files:
*.sln *.sln
@ -30,6 +31,7 @@
CMakeFiles/ CMakeFiles/
/pkg-config/jsoncpp.pc /pkg-config/jsoncpp.pc
jsoncpp_lib_static.dir/ jsoncpp_lib_static.dir/
compile_commands.json
# In case someone runs cmake in the root-dir: # In case someone runs cmake in the root-dir:
/CMakeCache.txt /CMakeCache.txt

View File

@ -116,14 +116,18 @@ template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
* Return iterator that would be the new end of the range [begin,end), if we * Return iterator that would be the new end of the range [begin,end), if we
* were to delete zeros in the end of string, but not the last zero before '.'. * were to delete zeros in the end of string, but not the last zero before '.'.
*/ */
template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) { template <typename Iter>
Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) {
for (; begin != end; --end) { for (; begin != end; --end) {
if (*(end - 1) != '0') { if (*(end - 1) != '0') {
return end; return end;
} }
// Don't delete the last zero before the decimal point. // Don't delete the last zero before the decimal point.
if (begin != (end - 1) && *(end - 2) == '.') { if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') {
return end; if (precision) {
return end;
}
return end - 2;
} }
} }
return end; return end;

View File

@ -154,16 +154,18 @@ String valueToString(double value, bool useSpecialFloats,
buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
// strip the zero padding from the right
if (precisionType == PrecisionType::decimalPlaces) {
buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
}
// try to ensure we preserve the fact that this was given to us as a double on // try to ensure we preserve the fact that this was given to us as a double on
// input // input
if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
buffer += ".0"; buffer += ".0";
} }
// strip the zero padding from the right
if (precisionType == PrecisionType::decimalPlaces) {
buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end(), precision),
buffer.end());
}
return buffer; return buffer;
} }
} // namespace } // namespace

View File

@ -2005,6 +2005,34 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, precision) {
result = Json::writeString(b, v); result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result); JSONTEST_ASSERT_STRING_EQUAL(expected, result);
b.settings_["precision"] = 0;
b.settings_["precisionType"] = "decimal";
v = 123.56345694873740545068;
expected = "124";
result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
b.settings_["precision"] = 1;
b.settings_["precisionType"] = "decimal";
v = 1230.001;
expected = "1230.0";
result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
b.settings_["precision"] = 0;
b.settings_["precisionType"] = "decimal";
v = 1230.001;
expected = "1230";
result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
b.settings_["precision"] = 0;
b.settings_["precisionType"] = "decimal";
v = 1231.5;
expected = "1232";
result = Json::writeString(b, v);
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
b.settings_["precision"] = 10; b.settings_["precision"] = 10;
b.settings_["precisionType"] = "decimal"; b.settings_["precisionType"] = "decimal";
v = 0.23300000; v = 0.23300000;