Skip to content

Commit 9409824

Browse files
authored
Fix a precision bug of valueToString, prevent to give an error result… (open-source-parsers#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 <[email protected]>
1 parent 8954092 commit 9409824

File tree

4 files changed

+44
-8
lines changed

4 files changed

+44
-8
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
/libs/
1111
/doc/doxyfile
1212
/dist/
13+
/.cache/
1314

1415
# MSVC project files:
1516
*.sln
@@ -30,6 +31,7 @@
3031
CMakeFiles/
3132
/pkg-config/jsoncpp.pc
3233
jsoncpp_lib_static.dir/
34+
compile_commands.json
3335

3436
# In case someone runs cmake in the root-dir:
3537
/CMakeCache.txt

src/lib_json/json_tool.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,18 @@ template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
116116
* Return iterator that would be the new end of the range [begin,end), if we
117117
* were to delete zeros in the end of string, but not the last zero before '.'.
118118
*/
119-
template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
119+
template <typename Iter>
120+
Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) {
120121
for (; begin != end; --end) {
121122
if (*(end - 1) != '0') {
122123
return end;
123124
}
124125
// Don't delete the last zero before the decimal point.
125-
if (begin != (end - 1) && *(end - 2) == '.') {
126-
return end;
126+
if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') {
127+
if (precision) {
128+
return end;
129+
}
130+
return end - 2;
127131
}
128132
}
129133
return end;

src/lib_json/json_writer.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,18 @@ String valueToString(double value, bool useSpecialFloats,
154154

155155
buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
156156

157-
// strip the zero padding from the right
158-
if (precisionType == PrecisionType::decimalPlaces) {
159-
buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
160-
}
161-
162157
// try to ensure we preserve the fact that this was given to us as a double on
163158
// input
164159
if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
165160
buffer += ".0";
166161
}
162+
163+
// strip the zero padding from the right
164+
if (precisionType == PrecisionType::decimalPlaces) {
165+
buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end(), precision),
166+
buffer.end());
167+
}
168+
167169
return buffer;
168170
}
169171
} // namespace

src/test_lib_json/main.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,6 +2005,34 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, precision) {
20052005
result = Json::writeString(b, v);
20062006
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
20072007

2008+
b.settings_["precision"] = 0;
2009+
b.settings_["precisionType"] = "decimal";
2010+
v = 123.56345694873740545068;
2011+
expected = "124";
2012+
result = Json::writeString(b, v);
2013+
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
2014+
2015+
b.settings_["precision"] = 1;
2016+
b.settings_["precisionType"] = "decimal";
2017+
v = 1230.001;
2018+
expected = "1230.0";
2019+
result = Json::writeString(b, v);
2020+
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
2021+
2022+
b.settings_["precision"] = 0;
2023+
b.settings_["precisionType"] = "decimal";
2024+
v = 1230.001;
2025+
expected = "1230";
2026+
result = Json::writeString(b, v);
2027+
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
2028+
2029+
b.settings_["precision"] = 0;
2030+
b.settings_["precisionType"] = "decimal";
2031+
v = 1231.5;
2032+
expected = "1232";
2033+
result = Json::writeString(b, v);
2034+
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
2035+
20082036
b.settings_["precision"] = 10;
20092037
b.settings_["precisionType"] = "decimal";
20102038
v = 0.23300000;

0 commit comments

Comments
 (0)