@@ -118,21 +118,29 @@ JSONCPP_STRING valueToString(UInt value) {
118118#endif // # if defined(JSON_HAS_INT64)
119119
120120namespace {
121- JSONCPP_STRING valueToString (double value, bool useSpecialFloats, unsigned int precision) {
121+ JSONCPP_STRING valueToString (double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType ) {
122122 // Allocate a buffer that is more than large enough to store the 16 digits of
123123 // precision requested below.
124124 char buffer[36 ];
125125 int len = -1 ;
126126
127127 char formatString[15 ];
128- snprintf (formatString, sizeof (formatString), " %%.%ug" , precision);
128+ if (precisionType == PrecisionType::significantDigits) {
129+ snprintf (formatString, sizeof (formatString), " %%.%ug" , precision);
130+ } else {
131+ snprintf (formatString, sizeof (formatString), " %%.%uf" , precision);
132+ }
129133
130134 // Print into the buffer. We need not request the alternative representation
131135 // that always has a decimal point because JSON doesn't distinguish the
132136 // concepts of reals and integers.
133137 if (isfinite (value)) {
134138 len = snprintf (buffer, sizeof (buffer), formatString, value);
135139 fixNumericLocale (buffer, buffer + len);
140+ // to delete use-less too much zeros in the end of string
141+ if (precisionType == PrecisionType::decimalPlaces) {
142+ fixZerosInTheEnd (buffer, buffer + len);
143+ }
136144
137145 // try to ensure we preserve the fact that this was given to us as a double on input
138146 if (!strchr (buffer, ' .' ) && !strchr (buffer, ' e' )) {
@@ -154,7 +162,9 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
154162}
155163}
156164
157- JSONCPP_STRING valueToString (double value) { return valueToString (value, false , 17 ); }
165+ JSONCPP_STRING valueToString (double value, unsigned int precision, PrecisionType precisionType) {
166+ return valueToString (value, false , precision, precisionType);
167+ }
158168
159169JSONCPP_STRING valueToString (bool value) { return value ? " true" : " false" ; }
160170
@@ -856,7 +866,8 @@ struct BuiltStyledStreamWriter : public StreamWriter
856866 JSONCPP_STRING const & nullSymbol,
857867 JSONCPP_STRING const & endingLineFeedSymbol,
858868 bool useSpecialFloats,
859- unsigned int precision);
869+ unsigned int precision,
870+ PrecisionType precisionType);
860871 int write (Value const & root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
861872private:
862873 void writeValue (Value const & value);
@@ -885,6 +896,7 @@ struct BuiltStyledStreamWriter : public StreamWriter
885896 bool indented_ : 1 ;
886897 bool useSpecialFloats_ : 1 ;
887898 unsigned int precision_;
899+ PrecisionType precisionType_;
888900};
889901BuiltStyledStreamWriter::BuiltStyledStreamWriter (
890902 JSONCPP_STRING const & indentation,
@@ -893,7 +905,8 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
893905 JSONCPP_STRING const & nullSymbol,
894906 JSONCPP_STRING const & endingLineFeedSymbol,
895907 bool useSpecialFloats,
896- unsigned int precision)
908+ unsigned int precision,
909+ PrecisionType precisionType)
897910 : rightMargin_(74 )
898911 , indentation_(indentation)
899912 , cs_(cs)
@@ -904,6 +917,7 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
904917 , indented_(false )
905918 , useSpecialFloats_(useSpecialFloats)
906919 , precision_(precision)
920+ , precisionType_(precisionType)
907921{
908922}
909923int BuiltStyledStreamWriter::write (Value const & root, JSONCPP_OSTREAM* sout)
@@ -933,7 +947,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
933947 pushValue (valueToString (value.asLargestUInt ()));
934948 break ;
935949 case realValue:
936- pushValue (valueToString (value.asDouble (), useSpecialFloats_, precision_));
950+ pushValue (valueToString (value.asDouble (), useSpecialFloats_, precision_, precisionType_ ));
937951 break ;
938952 case stringValue:
939953 {
@@ -1145,6 +1159,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
11451159{
11461160 JSONCPP_STRING indentation = settings_[" indentation" ].asString ();
11471161 JSONCPP_STRING cs_str = settings_[" commentStyle" ].asString ();
1162+ JSONCPP_STRING pt_str = settings_[" precisionType" ].asString ();
11481163 bool eyc = settings_[" enableYAMLCompatibility" ].asBool ();
11491164 bool dnp = settings_[" dropNullPlaceholders" ].asBool ();
11501165 bool usf = settings_[" useSpecialFloats" ].asBool ();
@@ -1157,6 +1172,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
11571172 } else {
11581173 throwRuntimeError (" commentStyle must be 'All' or 'None'" );
11591174 }
1175+ PrecisionType precisionType (significantDigits);
1176+ if (pt_str == " significant" ) {
1177+ precisionType = PrecisionType::significantDigits;
1178+ } else if (pt_str == " decimal" ) {
1179+ precisionType = PrecisionType::decimalPlaces;
1180+ } else {
1181+ throwRuntimeError (" precisionType must be 'significant' or 'decimal'" );
1182+ }
11601183 JSONCPP_STRING colonSymbol = " : " ;
11611184 if (eyc) {
11621185 colonSymbol = " : " ;
@@ -1171,7 +1194,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
11711194 JSONCPP_STRING endingLineFeedSymbol;
11721195 return new BuiltStyledStreamWriter (
11731196 indentation, cs,
1174- colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre );
1197+ colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre , precisionType );
11751198}
11761199static void getValidWriterKeys (std::set<JSONCPP_STRING>* valid_keys)
11771200{
@@ -1182,6 +1205,7 @@ static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
11821205 valid_keys->insert (" dropNullPlaceholders" );
11831206 valid_keys->insert (" useSpecialFloats" );
11841207 valid_keys->insert (" precision" );
1208+ valid_keys->insert (" precisionType" );
11851209}
11861210bool StreamWriterBuilder::validate (Json::Value* invalid) const
11871211{
@@ -1214,6 +1238,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
12141238 (*settings)[" dropNullPlaceholders" ] = false ;
12151239 (*settings)[" useSpecialFloats" ] = false ;
12161240 (*settings)[" precision" ] = 17 ;
1241+ (*settings)[" precisionType" ] = " significant" ;
12171242 // ! [StreamWriterBuilderDefaults]
12181243}
12191244
0 commit comments