diff options
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 21 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 21 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.h | 4 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.qdoc | 17 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_tools.cpp | 30 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_tools_p.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/qvariant.pro | 5 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 51 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qlocale/test/test.pro | 4 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qlocale/tst_qlocale.cpp | 83 |
10 files changed, 173 insertions, 67 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index fdcbdb1c45..1e755cf5d8 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -56,6 +56,7 @@ #include "qbytearraylist.h" #endif #include "private/qvariant_p.h" +#include "private/qlocale_p.h" #include "qmetatype_p.h" #include <qmetaobject.h> @@ -71,18 +72,6 @@ QT_BEGIN_NAMESPACE -#ifndef DBL_MANT_DIG -# define DBL_MANT_DIG 53 -#endif -#ifndef FLT_MANT_DIG -# define FLT_MANT_DIG 24 -#endif - -const int log10_2_10000 = 30103; // log10(2) * 100000 -// same as C++11 std::numeric_limits<T>::max_digits10 -const int max_digits10_double = (DBL_MANT_DIG * log10_2_10000) / 100000 + 2; -const int max_digits10_float = (FLT_MANT_DIG * log10_2_10000) / 100000 + 2; - namespace { class HandlersManager { @@ -433,10 +422,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *str = QString::number(qMetaTypeUNumber(d)); break; case QMetaType::Float: - *str = QString::number(d->data.f, 'g', max_digits10_float); + *str = QString::number(d->data.f, 'g', QLocale::FloatingPointShortest); break; case QVariant::Double: - *str = QString::number(d->data.d, 'g', max_digits10_double); + *str = QString::number(d->data.d, 'g', QLocale::FloatingPointShortest); break; #if !defined(QT_NO_DATESTRING) case QVariant::Date: @@ -625,10 +614,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *ba = v_cast<QString>(d)->toUtf8(); break; case QVariant::Double: - *ba = QByteArray::number(d->data.d, 'g', max_digits10_double); + *ba = QByteArray::number(d->data.d, 'g', QLocale::FloatingPointShortest); break; case QMetaType::Float: - *ba = QByteArray::number(d->data.f, 'g', max_digits10_float); + *ba = QByteArray::number(d->data.f, 'g', QLocale::FloatingPointShortest); break; case QMetaType::Char: case QMetaType::SChar: diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index dcb77a2c1b..072d62f5c2 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2743,7 +2743,7 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q const QChar exponential, const QChar group, const QChar decimal, double d, int precision, DoubleForm form, int width, unsigned flags) { - if (precision < 0) + if (precision != QLocale::FloatingPointShortest && precision < 0) precision = 6; if (width < 0) width = 0; @@ -2753,7 +2753,9 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q int decpt; int bufSize = 1; - if (form == DFDecimal) // optimize for numbers smaller than 512k + if (precision == QLocale::FloatingPointShortest) + bufSize += DoubleMaxSignificant; + else if (form == DFDecimal) // optimize for numbers between -512k and 512k bufSize += ((d > (1 << 19) || d < -(1 << 19)) ? DoubleMaxDigitsBeforeDecimal : 6) + precision; else // Add extra digit due to different interpretations of precision. Also, "nan" has to fit. @@ -2798,7 +2800,20 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q PrecisionMode mode = (flags & Alternate) ? PMSignificantDigits : PMChopTrailingZeros; - if (decpt != digits.length() && (decpt <= -4 || decpt > precision)) + int cutoff = precision < 0 ? 6 : precision; + // Find out which representation is shorter + if (precision == QLocale::FloatingPointShortest && decpt > 0) { + cutoff = digits.length() + 4; // 'e', '+'/'-', one digit exponent + if (decpt <= 10) { + ++cutoff; + } else { + cutoff += decpt > 100 ? 2 : 1; + } + if (!always_show_decpt && digits.length() > decpt) + ++cutoff; // decpt shown in exponent form, but not in decimal form + } + + if (decpt != digits.length() && (decpt <= -4 || decpt > cutoff)) num_str = exponentForm(_zero, decimal, exponential, group, plus, minus, digits, decpt, precision, mode, always_show_decpt); diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 729fd73a5d..f64a25bd00 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -848,6 +848,10 @@ public: }; Q_DECLARE_FLAGS(NumberOptions, NumberOption) + enum FloatingPointPrecisionOption { + FloatingPointShortest = -128 + }; + enum CurrencySymbolFormat { CurrencyIsoCode, CurrencySymbol, diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index c87e67cf17..03095d88d2 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -941,6 +941,23 @@ */ /*! + \enum QLocale::FloatingPointPrecisionOption + + This enum defines constants that can be given as precision to QString::number(), + QByteArray::number(), and QLocale::toString() when converting floats or doubles, + in order to express a variable number of digits as precision. + + \value FloatingPointShortest The conversion algorithm will try to find the + shortest accurate representation for the given number. "Accurate" means + that you get the exact same number back from an inverse conversion on + the generated string representation. + + \sa toString(), QString, QByteArray + + \since 5.7 +*/ + +/*! \enum QLocale::MeasurementSystem This enum defines which units are used for measurement. diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index 18d1096c12..890f63af0a 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -114,10 +114,16 @@ void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char * if (form == QLocaleData::DFExponent && precision >= 0) ++precision; - double_conversion::DoubleToStringConverter::DoubleToAscii(d, - form == QLocaleData::DFDecimal ? double_conversion::DoubleToStringConverter::FIXED : - double_conversion::DoubleToStringConverter::PRECISION, - precision, buf, bufSize, &sign, &length, &decpt); + double_conversion::DoubleToStringConverter::DtoaMode mode; + if (precision == QLocale::FloatingPointShortest) { + mode = double_conversion::DoubleToStringConverter::SHORTEST; + } else if (form == QLocaleData::DFSignificantDigits || form == QLocaleData::DFExponent) { + mode = double_conversion::DoubleToStringConverter::PRECISION; + } else { + mode = double_conversion::DoubleToStringConverter::FIXED; + } + double_conversion::DoubleToStringConverter::DoubleToAscii(d, mode, precision, buf, bufSize, + &sign, &length, &decpt); #else // QT_NO_DOUBLECONVERSION || QT_BOOTSTRAPPED // Cut the precision at 999, to fit it into the format string. We can't get more than 17 @@ -126,6 +132,8 @@ void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char * // to honor higher precisions. We define that at more than 999 digits that is not the case. if (precision > 999) precision = 999; + else if (precision == QLocale::FloatingPointShortest) + precision = QLocaleData::DoubleMaxSignificant; // "shortest" mode not supported by snprintf if (isZero(d)) { // Negative zero is expected as simple "0", not "-0". We cannot do d < 0, though. @@ -442,7 +450,7 @@ QString qlltoa(qlonglong l, int base, const QChar zero) } QString &decimalForm(QChar zero, QChar decimal, QChar group, - QString &digits, int decpt, uint precision, + QString &digits, int decpt, int precision, PrecisionMode pm, bool always_show_decpt, bool thousands_group) @@ -459,11 +467,11 @@ QString &decimalForm(QChar zero, QChar decimal, QChar group, if (pm == PMDecimalDigits) { uint decimal_digits = digits.length() - decpt; - for (uint i = decimal_digits; i < precision; ++i) + for (int i = decimal_digits; i < precision; ++i) digits.append(zero); } else if (pm == PMSignificantDigits) { - for (uint i = digits.length(); i < precision; ++i) + for (int i = digits.length(); i < precision; ++i) digits.append(zero); } else { // pm == PMChopTrailingZeros @@ -485,18 +493,18 @@ QString &decimalForm(QChar zero, QChar decimal, QChar group, QString &exponentForm(QChar zero, QChar decimal, QChar exponential, QChar group, QChar plus, QChar minus, - QString &digits, int decpt, uint precision, + QString &digits, int decpt, int precision, PrecisionMode pm, bool always_show_decpt) { int exp = decpt - 1; if (pm == PMDecimalDigits) { - for (uint i = digits.length(); i < precision + 1; ++i) + for (int i = digits.length(); i < precision + 1; ++i) digits.append(zero); } else if (pm == PMSignificantDigits) { - for (uint i = digits.length(); i < precision; ++i) + for (int i = digits.length(); i < precision; ++i) digits.append(zero); } else { // pm == PMChopTrailingZeros @@ -534,7 +542,7 @@ QString qdtoa(qreal d, int *decpt, int *sign) // Some versions of libdouble-conversion like an extra digit, probably for '\0' char result[QLocaleData::DoubleMaxSignificant + 1]; - doubleToAscii(d, QLocaleData::DFSignificantDigits, QLocaleData::DoubleMaxSignificant, result, + doubleToAscii(d, QLocaleData::DFSignificantDigits, QLocale::FloatingPointShortest, result, QLocaleData::DoubleMaxSignificant + 1, nonNullSign, length, nonNullDecpt); // Skip trailing zeroes. The DoubleMaxSignificant precision is the worst case. diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h index 840ae8f163..3ddf75d000 100644 --- a/src/corelib/tools/qlocale_tools_p.h +++ b/src/corelib/tools/qlocale_tools_p.h @@ -81,13 +81,13 @@ enum PrecisionMode { }; QString &decimalForm(QChar zero, QChar decimal, QChar group, - QString &digits, int decpt, uint precision, + QString &digits, int decpt, int precision, PrecisionMode pm, bool always_show_decpt, bool thousands_group); QString &exponentForm(QChar zero, QChar decimal, QChar exponential, QChar group, QChar plus, QChar minus, - QString &digits, int decpt, uint precision, + QString &digits, int decpt, int precision, PrecisionMode pm, bool always_show_decpt); diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro index a2dda809ad..33e8b6e2ad 100644 --- a/tests/auto/corelib/kernel/qvariant/qvariant.pro +++ b/tests/auto/corelib/kernel/qvariant/qvariant.pro @@ -1,8 +1,11 @@ CONFIG += testcase TARGET = tst_qvariant -QT = core testlib +QT = core-private testlib INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qvariant.cpp RESOURCES += qvariant.qrc DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 contains(QT_CONFIG, c++11): CONFIG += c++11 +!contains(QT_CONFIG, doubleconversion):!contains(QT_CONFIG, system-doubleconversion) { + DEFINES += QT_NO_DOUBLECONVERSION +} diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index de53ab1fa3..0c4efcd0c2 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -56,6 +56,7 @@ #include <QBuffer> #include "qnumeric.h" +#include <private/qlocale_p.h> #include "tst_qvariant_common.h" class CustomNonQObject; @@ -1028,7 +1029,11 @@ void tst_QVariant::toByteArray_data() QTest::newRow( "int" ) << QVariant( -123 ) << QByteArray( "-123" ); QTest::newRow( "uint" ) << QVariant( (uint)123 ) << QByteArray( "123" ); QTest::newRow( "double" ) << QVariant( 123.456 ) << QByteArray( "123.456" ); - QTest::newRow( "float" ) << QVariant( 123.456f ) << QByteArray( "123.456001" ); + + // Conversion from float to double adds bits of which the double-to-string converter doesn't + // know they're insignificant + QTest::newRow( "float" ) << QVariant( 123.456f ) << QByteArray( "123.45600128173828" ); + QTest::newRow( "longlong" ) << QVariant( (qlonglong)34 ) << QByteArray( "34" ); QTest::newRow( "ulonglong" ) << QVariant( (qulonglong)34 ) << QByteArray( "34" ); } @@ -1054,7 +1059,11 @@ void tst_QVariant::toString_data() QTest::newRow( "int" ) << QVariant( -123 ) << QString( "-123" ); QTest::newRow( "uint" ) << QVariant( (uint)123 ) << QString( "123" ); QTest::newRow( "double" ) << QVariant( 123.456 ) << QString( "123.456" ); - QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456001" ); + + // Conversion from float to double adds bits of which the double-to-string converter doesn't + // know they're insignificant + QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.45600128173828" ); + QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); @@ -1411,12 +1420,28 @@ void tst_QVariant::operator_eq_eq_data() QVariant mUIntQString(QString("42")); QVariant mDouble(42.11); +#ifdef QT_NO_DOUBLECONVERSION + // Without libdouble-conversion we don't get the shortest possible representation. QVariant mDoubleString(QByteArray("42.109999999999999")); - QVariant mDoubleQString(QString("42.109999999999999")); + QVariant mDoubleQString(QByteArray("42.109999999999999")); +#else + // You cannot fool the double-to-string conversion into producing insignificant digits with + // libdouble-conversion. You can, of course, add insignificant digits to the string and fool + // the double-to-double comparison after converting the string to a double. + QVariant mDoubleString(QByteArray("42.11")); + QVariant mDoubleQString(QString("42.11")); +#endif + // Float-to-double conversion produces insignificant extra bits. QVariant mFloat(42.11f); - QVariant mFloatString(QByteArray("42.1100006")); - QVariant mFloatQString(QString("42.1100006")); +#ifdef QT_NO_DOUBLECONVERSION + // The trailing '2' is not significant, but snprintf doesn't know this. + QVariant mFloatString(QByteArray("42.110000610351562")); + QVariant mFloatQString(QString("42.110000610351562")); +#else + QVariant mFloatString(QByteArray("42.11000061035156")); + QVariant mFloatQString(QString("42.11000061035156")); +#endif QVariant mLongLong((qlonglong)-42); QVariant mLongLongString(QByteArray("-42")); @@ -3374,10 +3399,11 @@ void tst_QVariant::numericalConvert() switch (v.userType()) { case QVariant::Double: - QCOMPARE(v.toString() , QString::number(num, 'g', DBL_MANT_DIG * std::log10(2.) + 2)); + QCOMPARE(v.toString() , QString::number(num, 'g', QLocale::FloatingPointShortest)); break; case QMetaType::Float: - QCOMPARE(v.toString() , QString::number(float(num), 'g', FLT_MANT_DIG * std::log10(2.) + 2)); + QCOMPARE(v.toString() , + QString::number(float(num), 'g', QLocale::FloatingPointShortest)); break; } } @@ -3613,8 +3639,17 @@ void tst_QVariant::moreCustomTypes() QCOMPARE(MyNotMovable::count, 0); { +#ifdef QT_NO_DOUBLECONVERSION + // snprintf cannot do "shortest" conversion and always adds noise. PLAY_WITH_VARIANT(12.12, false, "12.119999999999999", 12.12, true); - PLAY_WITH_VARIANT(12.12f, false, "12.1199999", 12.12f, true); +#else + // Double can be printed exactly with libdouble-conversion + PLAY_WITH_VARIANT(12.12, false, "12.12", 12.12, true); +#endif + + // Float is converted to double, adding insignificant bits + PLAY_WITH_VARIANT(12.12f, false, "12.119999885559082", 12.12f, true); + PLAY_WITH_VARIANT('a', false, "a", 'a', true); PLAY_WITH_VARIANT((unsigned char)('a'), false, "a", 'a', true); PLAY_WITH_VARIANT( quint8(12), false, "\xc", 12, true); diff --git a/tests/auto/corelib/tools/qlocale/test/test.pro b/tests/auto/corelib/tools/qlocale/test/test.pro index bb12758107..4777030dd7 100644 --- a/tests/auto/corelib/tools/qlocale/test/test.pro +++ b/tests/auto/corelib/tools/qlocale/test/test.pro @@ -4,6 +4,10 @@ QT = core testlib core-private embedded: QT += gui SOURCES = ../tst_qlocale.cpp +!contains(QT_CONFIG, doubleconversion):!contains(QT_CONFIG, system-doubleconversion) { + DEFINES += QT_NO_DOUBLECONVERSION +} + TARGET = ../tst_qlocale win32 { CONFIG(debug, debug|release) { diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 96b91f4fd4..683f7490e5 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -772,20 +772,28 @@ void tst_QLocale::doubleToString_data() QTest::addColumn<char>("mode"); QTest::addColumn<int>("precision"); - QTest::newRow("C 3.4 f 5") << QString("C") << QString("3.40000") << 3.4 << 'f' << 5; - QTest::newRow("C 3.4 f 0") << QString("C") << QString("3") << 3.4 << 'f' << 0; - QTest::newRow("C 3.4 e 5") << QString("C") << QString("3.40000e+00") << 3.4 << 'e' << 5; - QTest::newRow("C 3.4 e 0") << QString("C") << QString("3e+00") << 3.4 << 'e' << 0; - QTest::newRow("C 3.4 g 5") << QString("C") << QString("3.4") << 3.4 << 'g' << 5; - QTest::newRow("C 3.4 g 1") << QString("C") << QString("3") << 3.4 << 'g' << 1; - - QTest::newRow("C 3.4 f 1") << QString("C") << QString("3.4") << 3.4 << 'f' << 1; - QTest::newRow("C 3.4 e 1") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << 1; - QTest::newRow("C 3.4 g 2") << QString("C") << QString("3.4") << 3.4 << 'g' << 2; - - QTest::newRow("de_DE 3,4 f 1") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << 1; - QTest::newRow("de_DE 3,4 e 1") << QString("de_DE") << QString("3,4e+00") << 3.4 << 'e' << 1; - QTest::newRow("de_DE 3,4 g 2") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << 2; + int shortest = QLocale::FloatingPointShortest; + + QTest::newRow("C 3.4 f 5") << QString("C") << QString("3.40000") << 3.4 << 'f' << 5; + QTest::newRow("C 3.4 f 0") << QString("C") << QString("3") << 3.4 << 'f' << 0; + QTest::newRow("C 3.4 e 5") << QString("C") << QString("3.40000e+00") << 3.4 << 'e' << 5; + QTest::newRow("C 3.4 e 0") << QString("C") << QString("3e+00") << 3.4 << 'e' << 0; + QTest::newRow("C 3.4 g 5") << QString("C") << QString("3.4") << 3.4 << 'g' << 5; + QTest::newRow("C 3.4 g 1") << QString("C") << QString("3") << 3.4 << 'g' << 1; + + QTest::newRow("C 3.4 f 1") << QString("C") << QString("3.4") << 3.4 << 'f' << 1; + QTest::newRow("C 3.4 f -") << QString("C") << QString("3.4") << 3.4 << 'f' << shortest; + QTest::newRow("C 3.4 e 1") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << 1; + QTest::newRow("C 3.4 e -") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << shortest; + QTest::newRow("C 3.4 g 2") << QString("C") << QString("3.4") << 3.4 << 'g' << 2; + QTest::newRow("C 3.4 g -") << QString("C") << QString("3.4") << 3.4 << 'g' << shortest; + + QTest::newRow("de_DE 3,4 f 1") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << 1; + QTest::newRow("de_DE 3,4 f -") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << shortest; + QTest::newRow("de_DE 3,4 e 1") << QString("de_DE") << QString("3,4e+00") << 3.4 << 'e' << 1; + QTest::newRow("de_DE 3,4 e -") << QString("de_DE") << QString("3,4e+00") << 3.4 << 'e' << shortest; + QTest::newRow("de_DE 3,4 g 2") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << 2; + QTest::newRow("de_DE 3,4 g -") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << shortest; QTest::newRow("C 0.035003945 f 12") << QString("C") << QString("0.035003945000") << 0.035003945 << 'f' << 12; QTest::newRow("C 0.035003945 f 6") << QString("C") << QString("0.035004") << 0.035003945 << 'f' << 6; @@ -794,13 +802,19 @@ void tst_QLocale::doubleToString_data() QTest::newRow("C 0.035003945 g 11") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 11; QTest::newRow("C 0.035003945 g 5") << QString("C") << QString("0.035004") << 0.035003945 << 'g' << 5; - QTest::newRow("C 0.035003945 f 9") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << 9; - QTest::newRow("C 0.035003945 e 7") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << 7; - QTest::newRow("C 0.035003945 g 8") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 8; + QTest::newRow("C 0.035003945 f 9") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << 9; + QTest::newRow("C 0.035003945 f -") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << shortest; + QTest::newRow("C 0.035003945 e 7") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << 7; + QTest::newRow("C 0.035003945 e -") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << shortest; + QTest::newRow("C 0.035003945 g 8") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 8; + QTest::newRow("C 0.035003945 g -") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << shortest; - QTest::newRow("de_DE 0,035003945 f 9") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << 9; - QTest::newRow("de_DE 0,035003945 e 7") << QString("de_DE") << QString("3,5003945e-02") << 0.035003945 << 'e' << 7; - QTest::newRow("de_DE 0,035003945 g 8") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << 8; + QTest::newRow("de_DE 0,035003945 f 9") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << 9; + QTest::newRow("de_DE 0,035003945 f -") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << shortest; + QTest::newRow("de_DE 0,035003945 e 7") << QString("de_DE") << QString("3,5003945e-02") << 0.035003945 << 'e' << 7; + QTest::newRow("de_DE 0,035003945 e -") << QString("de_DE") << QString("3,5003945e-02") << 0.035003945 << 'e' << shortest; + QTest::newRow("de_DE 0,035003945 g 8") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << 8; + QTest::newRow("de_DE 0,035003945 g -") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << shortest; QTest::newRow("C 0.000003945 f 12") << QString("C") << QString("0.000003945000") << 0.000003945 << 'f' << 12; QTest::newRow("C 0.000003945 f 6") << QString("C") << QString("0.000004") << 0.000003945 << 'f' << 6; @@ -809,13 +823,19 @@ void tst_QLocale::doubleToString_data() QTest::newRow("C 0.000003945 g 7") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 7; QTest::newRow("C 0.000003945 g 1") << QString("C") << QString("4e-06") << 0.000003945 << 'g' << 1; - QTest::newRow("C 0.000003945 f 9") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << 9; - QTest::newRow("C 0.000003945 e 3") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << 3; - QTest::newRow("C 0.000003945 g 4") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 4; + QTest::newRow("C 0.000003945 f 9") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << 9; + QTest::newRow("C 0.000003945 f -") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << shortest; + QTest::newRow("C 0.000003945 e 3") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << 3; + QTest::newRow("C 0.000003945 e -") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << shortest; + QTest::newRow("C 0.000003945 g 4") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 4; + QTest::newRow("C 0.000003945 g -") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << shortest; - QTest::newRow("de_DE 0,000003945 f 9") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << 9; - QTest::newRow("de_DE 0,000003945 e 3") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'e' << 3; - QTest::newRow("de_DE 0,000003945 g 4") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'g' << 4; + QTest::newRow("de_DE 0,000003945 f 9") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << 9; + QTest::newRow("de_DE 0,000003945 f -") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << shortest; + QTest::newRow("de_DE 0,000003945 e 3") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'e' << 3; + QTest::newRow("de_DE 0,000003945 e -") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'e' << shortest; + QTest::newRow("de_DE 0,000003945 g 4") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'g' << 4; + QTest::newRow("de_DE 0,000003945 g -") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'g' << shortest; QTest::newRow("C 12456789012 f 3") << QString("C") << QString("12456789012.000") << 12456789012.0 << 'f' << 3; QTest::newRow("C 12456789012 e 13") << QString("C") << QString("1.2456789012000e+10") << 12456789012.0 << 'e' << 13; @@ -824,12 +844,18 @@ void tst_QLocale::doubleToString_data() QTest::newRow("C 12456789012 g 8") << QString("C") << QString("1.2456789e+10") << 12456789012.0 << 'g' << 8; QTest::newRow("C 12456789012 f 0") << QString("C") << QString("12456789012") << 12456789012.0 << 'f' << 0; + QTest::newRow("C 12456789012 f -") << QString("C") << QString("12456789012") << 12456789012.0 << 'f' << shortest; QTest::newRow("C 12456789012 e 10") << QString("C") << QString("1.2456789012e+10") << 12456789012.0 << 'e' << 10; + QTest::newRow("C 12456789012 e -") << QString("C") << QString("1.2456789012e+10") << 12456789012.0 << 'e' << shortest; QTest::newRow("C 12456789012 g 11") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << 11; + QTest::newRow("C 12456789012 g -") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << shortest; QTest::newRow("de_DE 12456789012 f 0") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'f' << 0; + QTest::newRow("de_DE 12456789012 f -") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'f' << shortest; QTest::newRow("de_DE 12456789012 e 10") << QString("de_DE") << QString("1,2456789012e+10") << 12456789012.0 << 'e' << 10; + QTest::newRow("de_DE 12456789012 e -") << QString("de_DE") << QString("1,2456789012e+10") << 12456789012.0 << 'e' << shortest; QTest::newRow("de_DE 12456789012 g 11") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'g' << 11; + QTest::newRow("de_DE 12456789012 g -") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'g' << shortest; } void tst_QLocale::doubleToString() @@ -840,6 +866,11 @@ void tst_QLocale::doubleToString() QFETCH(char, mode); QFETCH(int, precision); +#ifdef QT_NO_DOUBLECONVERSION + if (precision == QLocale::FloatingPointShortest) + QSKIP("'Shortest' double conversion is not that short without libdouble-conversion"); +#endif + const QLocale locale(locale_name); QCOMPARE(locale.toString(num, mode, precision), num_str); |