From 721d732b40bb3d698f28e7754eae2ba23fa325f3 Mon Sep 17 00:00:00 2001 From: Tom Poole Date: Fri, 7 Dec 2018 13:52:54 +0000 Subject: [PATCH] Reverted the numberOfDecimalPlaces behaviour of the String constructor --- .../juce_AudioProcessorValueTreeState.cpp | 8 ++-- modules/juce_core/text/juce_String.cpp | 43 ++---------------- modules/juce_core/text/juce_String.h | 16 +++---- modules/juce_core/xml/juce_XmlElement.cpp | 45 ++++++++++++++++++- 4 files changed, 59 insertions(+), 53 deletions(-) diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index 89edbe6f83..dd33601906 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -797,10 +797,10 @@ static struct ParameterAdapterTests final : public UnitTest expectEquals (adapter.getTextForDenormalisedValue (value), expected); }; - test ({ -100, 100 }, 0, "0.0"); - test ({ -2.5, 12.5 }, 10, "10.0"); - test ({ -20, -10 }, -15, "-15.0"); - test ({ 0, 7.5 }, 2.5, "2.5"); + test ({ -100, 100 }, 0, "0.00"); + test ({ -2.5, 12.5 }, 10, "10.00"); + test ({ -20, -10 }, -15, "-15.00"); + test ({ 0, 7.5 }, 2.5, "2.50"); } beginTest ("Text can be converted to floats"); diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 2d743f137e..9509dc693d 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -469,30 +469,7 @@ namespace NumberToStringConverters o << n; } - return findLengthWithoutTrailingZeros (pbase(), pptr()); - } - - static size_t findLengthWithoutTrailingZeros (const char* const start, - const char* const end) - { - 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); + return (size_t) (pptr() - pbase()); } }; @@ -505,14 +482,7 @@ namespace NumberToStringConverters auto v = (int64) (std::pow (10.0, numDecPlaces) * std::abs (n) + 0.5); *--t = (char) 0; - // skip trailing zeros - while (numDecPlaces > 1 && (v % 10) == 0) - { - v /= 10; - --numDecPlaces; - } - - while (v > 0 || numDecPlaces >= 0) + while (numDecPlaces >= 0 || v > 0) { if (numDecPlaces == 0) *--t = '.'; @@ -2523,14 +2493,7 @@ public: expect (String::toHexString (data, 8, 1).equalsIgnoreCase ("01 02 03 04 0a 0b 0c 0d")); expect (String::toHexString (data, 8, 2).equalsIgnoreCase ("0102 0304 0a0b 0c0d")); - expectEquals (String (2589410.5894, 7), String ("2589410.5894")); - expectEquals (String (2589410.5894, 4), String ("2589410.5894")); - expectEquals (String (100000.0, 1), String ("100000.0")); - expectEquals (String (100000.0, 10), String ("100000.0")); - expectEquals (String (100000.001, 8), String ("100000.001")); - expectEquals (String (100000.001, 4), String ("100000.001")); - expectEquals (String (100000.001, 3), String ("100000.001")); - expectEquals (String (100000.001, 2), String ("100000.0")); + expectEquals (String (2589410.5894, 7), String ("2589410.5894000")); beginTest ("Subsections"); String s3; diff --git a/modules/juce_core/text/juce_String.h b/modules/juce_core/text/juce_String.h index 946c25aad9..66bcfa418a 100644 --- a/modules/juce_core/text/juce_String.h +++ b/modules/juce_core/text/juce_String.h @@ -962,23 +962,23 @@ public: /** Creates a string representing this floating-point number. @param floatValue the value to convert to a string - @param maxNumberOfDecimalPlaces if this is > 0, it will format the number using no more - decimal places than this amount, and will not use exponent - notation. If 0 or less, it will use a default format, and + @param numberOfDecimalPlaces if this is > 0, it will format the number using that many + decimal places, adding trailing zeros as required, and + will not use exponent notation. If 0 or less, it will use exponent notation if necessary. @see getDoubleValue, getIntValue */ - String (float floatValue, int maxNumberOfDecimalPlaces); + String (float floatValue, int numberOfDecimalPlaces); /** Creates a string representing this floating-point number. @param doubleValue the value to convert to a string - @param maxNumberOfDecimalPlaces if this is > 0, it will format the number using no more - decimal places than this amount, and will not use exponent - notation. If 0 or less, it will use a default format, and + @param numberOfDecimalPlaces if this is > 0, it will format the number using that many + decimal places, adding trailing zeros as required, and + will not use exponent notation. If 0 or less, it will use exponent notation if necessary. @see getFloatValue, getIntValue */ - String (double doubleValue, int maxNumberOfDecimalPlaces); + String (double doubleValue, int numberOfDecimalPlaces); // Automatically creating a String from a bool opens up lots of nasty type conversion edge cases. // If you want a String representation of a bool you can cast the bool to an int first. diff --git a/modules/juce_core/xml/juce_XmlElement.cpp b/modules/juce_core/xml/juce_XmlElement.cpp index 18c0a60673..4db0349fc6 100644 --- a/modules/juce_core/xml/juce_XmlElement.cpp +++ b/modules/juce_core/xml/juce_XmlElement.cpp @@ -578,9 +578,26 @@ 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, String (number, 20)); + setAttribute (attributeName, trimTrailingZeros ({ number, 20 })); } void XmlElement::removeAttribute (const Identifier& attributeName) noexcept @@ -923,4 +940,30 @@ void XmlElement::deleteAllTextElements() noexcept } } +//============================================================================== +#if JUCE_UNIT_TESTS + +class XmlElementTests : public UnitTest +{ +public: + XmlElementTests() : UnitTest ("XmlElement", "XML") {} + + void runTest() override + { + { + beginTest ("Trailing zeros"); + + auto element = std::make_unique ("test"); + Identifier d ("d"); + + element->setAttribute (d, 3.0); + expectEquals (element->getStringAttribute (d), String ("3.0")); + } + } +}; + +static XmlElementTests xmlElementTests; + +#endif + } // namespace juce