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>
bb10
Edward Welbourne 2018-06-08 17:37:49 +02:00
parent 6afd5990c7
commit 91f3687ee5
2 changed files with 29 additions and 8 deletions

View File

@ -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) {

View File

@ -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();