diff --git a/modules/juce_core/javascript/juce_JSON.cpp b/modules/juce_core/javascript/juce_JSON.cpp index 74f6bc8359..073659b2c1 100644 --- a/modules/juce_core/javascript/juce_JSON.cpp +++ b/modules/juce_core/javascript/juce_JSON.cpp @@ -351,9 +351,14 @@ struct JSONFormatter auto d = static_cast (v); if (juce_isfinite (d)) - out << String (d, maximumDecimalPlaces); + { + String doubleString (d, maximumDecimalPlaces); + out << doubleString.substring (0, (int) CharacterFunctions::findLengthWithoutTrailingZeros (doubleString.getCharPointer())); + } else + { out << "null"; + } } else if (v.isArray()) { diff --git a/modules/juce_core/text/juce_CharacterFunctions.h b/modules/juce_core/text/juce_CharacterFunctions.h index 7c6e55b5dd..56de835025 100644 --- a/modules/juce_core/text/juce_CharacterFunctions.h +++ b/modules/juce_core/text/juce_CharacterFunctions.h @@ -378,6 +378,35 @@ public: return readDoubleValue (text); } + /** If the input is a string representation of a floating-point number, this will + find the length of the string without any trailing zeros. + */ + template + static size_t findLengthWithoutTrailingZeros (CharPointerType text) + { + auto start = text; + auto end = text + ((int) text.length()); + + for (auto e = end; e > start + 1; --e) + { + auto lastChar = *(e - 1); + + if (lastChar != '0') + { + if (lastChar == '.') + return (size_t) (e + 1 - start); + + for (auto s = start; s < e; ++s) + if (*s == '.') + return (size_t) (e - start); + + break; + } + } + + return (size_t) (end - start); + } + //============================================================================== /** Parses a character string, to read an integer value. */ template diff --git a/modules/juce_core/xml/juce_XmlElement.cpp b/modules/juce_core/xml/juce_XmlElement.cpp index 4db0349fc6..5939d9f12b 100644 --- a/modules/juce_core/xml/juce_XmlElement.cpp +++ b/modules/juce_core/xml/juce_XmlElement.cpp @@ -578,26 +578,11 @@ void XmlElement::setAttribute (const Identifier& attributeName, const int number setAttribute (attributeName, String (number)); } -static String trimTrailingZeros (const String& input) -{ - auto pointPos = input.indexOfChar ('.'); - - if (pointPos == -1) - return input; - - auto start = input.getCharPointer(); - auto minPos = start + pointPos + 1; - auto ptr = start + input.length() - 1; - - while (ptr != minPos && *ptr == '0') - --ptr; - - return input.substring (0, (int) (ptr - start) + 1); -} - void XmlElement::setAttribute (const Identifier& attributeName, const double number) { - setAttribute (attributeName, trimTrailingZeros ({ number, 20 })); + String doubleString (number, 20); + setAttribute (attributeName, + doubleString.substring (0, (int) CharacterFunctions::findLengthWithoutTrailingZeros (doubleString.getCharPointer()))); } void XmlElement::removeAttribute (const Identifier& attributeName) noexcept