summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2018-06-08 17:37:49 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2018-06-14 09:13:36 +0000
commit91f3687ee51db83d9018bd61c3fbc736c6e9912e (patch)
tree4a6ba0a2e5f91dc9ebe19f400bbc5506f81b6375
parent6afd5990c79d86d4136b41018066c05c95d1b0d2 (diff)
Make QString's formatting of doubles be consistent with other places
QString::sprintf(), like the C printf-family, always includes two digits in any exponent it outputs. Up to 5.6, number() and arg() taking a double did the same; but changes at 5.7 to enable opting out of the leading zero this implies for a single-digit exponent accidentally opted out of it in args() and number(). This commit fixes number() and arg() to include QLocaleData::ZeroPadExponent in the flags they pass down to the C locale's doubleToString(), restoring the prior behavior, including consistency with sprintf(). [ChangeLog][QtCore][QString] Formatting of doubles with single-digit exponent, by number() or args(), now includes a leading zero in that exponent, consistently with sprintf(), as it did up to 5.6. Task-number: QTBUG-63620 Change-Id: I10c491902b8556e9f19e605177ead8d9fd32abd9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/corelib/tools/qstring.cpp14
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp23
2 files changed, 29 insertions, 8 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index a4b34263df..3787c496b2 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -7414,13 +7414,12 @@ QString QString::number(qulonglong n, int base)
QString QString::number(double n, char f, int prec)
{
QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
- uint flags = 0;
+ uint flags = QLocaleData::ZeroPadExponent;
if (qIsUpper(f))
- flags = QLocaleData::CapitalEorX;
- f = qToLower(f);
+ flags |= QLocaleData::CapitalEorX;
- switch (f) {
+ switch (qToLower(f)) {
case 'f':
form = QLocaleData::DFDecimal;
break;
@@ -8487,14 +8486,13 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha
unsigned flags = QLocaleData::NoFlags;
if (fillChar == QLatin1Char('0'))
- flags = QLocaleData::ZeroPadded;
+ flags |= QLocaleData::ZeroPadded;
if (qIsUpper(fmt))
flags |= QLocaleData::CapitalEorX;
- fmt = qToLower(fmt);
QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
- switch (fmt) {
+ switch (qToLower(fmt)) {
case 'f':
form = QLocaleData::DFDecimal;
break;
@@ -8513,7 +8511,7 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha
QString arg;
if (d.occurrences > d.locale_occurrences)
- arg = QLocaleData::c()->doubleToString(a, prec, form, fieldWidth, flags);
+ arg = QLocaleData::c()->doubleToString(a, prec, form, fieldWidth, flags | QLocaleData::ZeroPadExponent);
QString locale_arg;
if (d.locale_occurrences > 0) {
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 28014840a3..2074c9789a 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -516,6 +516,7 @@ private slots:
void toUcs4();
void arg();
void number();
+ void doubleOut();
void arg_fillChar_data();
void arg_fillChar();
void capacity_data();
@@ -4882,6 +4883,28 @@ void tst_QString::number()
#endif
}
+void tst_QString::doubleOut()
+{
+ // Regression test for QTBUG-63620; the first two paths lost the exponent's
+ // leading 0 at 5.7; C's printf() family guarantee a two-digit exponent (in
+ // contrast with ECMAScript, which forbids leading zeros).
+ const QString expect(QStringLiteral("1e-06"));
+ const double micro = 1e-6;
+ QCOMPARE(QString::number(micro), expect);
+ QCOMPARE(QString("%1").arg(micro), expect);
+ {
+ QString text;
+ text.sprintf("%g", micro);
+ QCOMPARE(text, expect);
+ }
+ {
+ QString text;
+ QTextStream stream(&text);
+ stream << micro;
+ QCOMPARE(text, expect);
+ }
+}
+
void tst_QString::capacity_data()
{
length_data();