Make RuntimeHelpers::numberToString() comply with EcmaScript
We could use DoubleToStringConverter::EcmaScriptConverter().ToShortest() here, but we'd have to #ifdef it for the case that we're using the libc double conversion. As the formatting does not produce a lot of code I decided against that. Task-number: QTBUG-50131 Change-Id: If7a2ef8063b57ab35cda4a60d8ddd65442d70103 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This commit is contained in:
parent
d19acb0cbb
commit
881bb537c9
|
@ -225,8 +225,36 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
|
|||
}
|
||||
|
||||
if (radix == 10) {
|
||||
const NumberLocale *locale = NumberLocale::instance();
|
||||
*result = locale->toString(num, 'g', locale->defaultDoublePrecision);
|
||||
// We cannot use our usual locale->toString(...) here, because EcmaScript has special rules
|
||||
// about the longest permissible number, depending on if it's <0 or >0.
|
||||
const int ecma_shortest_low = -6;
|
||||
const int ecma_shortest_high = 21;
|
||||
|
||||
const QLatin1Char zero('0');
|
||||
const QLatin1Char dot('.');
|
||||
|
||||
int decpt = 0;
|
||||
int sign = 0;
|
||||
*result = qdtoa(num, &decpt, &sign);
|
||||
|
||||
if (decpt <= ecma_shortest_low || decpt > ecma_shortest_high) {
|
||||
if (result->length() > 1)
|
||||
result->insert(1, dot);
|
||||
result->append(QLatin1Char('e'));
|
||||
if (decpt > 0)
|
||||
result->append(QLatin1Char('+'));
|
||||
result->append(QString::number(decpt - 1));
|
||||
} else if (decpt <= 0) {
|
||||
result->prepend(QString::fromLatin1("0.%1").arg(QString().fill(zero, -decpt)));
|
||||
} else if (decpt < result->length()) {
|
||||
result->insert(decpt, dot);
|
||||
} else {
|
||||
result->append(QString().fill(zero, decpt - result->length()));
|
||||
}
|
||||
|
||||
if (sign)
|
||||
result->prepend(QLatin1Char('-'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,27 @@ import QtQuick 2.0
|
|||
|
||||
QtObject {
|
||||
property double a: 3.4
|
||||
property string b: a
|
||||
property string a1: a
|
||||
property string a2: a + ""
|
||||
|
||||
property double c: 0.035003945
|
||||
property string d: c
|
||||
property double b: 0.035003945
|
||||
property string b1: b
|
||||
property string b2: b + ""
|
||||
|
||||
property double c: 0.0000012345
|
||||
property string c1: c
|
||||
property string c2: c + ""
|
||||
|
||||
property double d: 0.00000012345
|
||||
property string d1: d
|
||||
property string d2: d + ""
|
||||
|
||||
property double e: 100000000000000000000
|
||||
property string e1: e
|
||||
property string e2: e + ""
|
||||
|
||||
property double f: 1000000000000000000000
|
||||
property string f1: f
|
||||
property string f2: f + ""
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,8 @@ private slots:
|
|||
void registeredCompositeTypeProperty();
|
||||
void deeplyNestedObject();
|
||||
void readOnlyDynamicProperties();
|
||||
|
||||
void floatToStringPrecision_data();
|
||||
void floatToStringPrecision();
|
||||
|
||||
void copy();
|
||||
|
@ -2055,21 +2057,43 @@ void tst_qqmlproperty::readOnlyDynamicProperties()
|
|||
delete obj;
|
||||
}
|
||||
|
||||
void tst_qqmlproperty::floatToStringPrecision_data()
|
||||
{
|
||||
QTest::addColumn<QString>("propertyName");
|
||||
QTest::addColumn<double>("number");
|
||||
QTest::addColumn<QString>("qtString");
|
||||
QTest::addColumn<QString>("jsString");
|
||||
|
||||
QTest::newRow("3.4") << "a" << 3.4 << "3.4" << "3.4";
|
||||
QTest::newRow("0.035003945") << "b" << 0.035003945 << "0.035003945" << "0.035003945";
|
||||
QTest::newRow("0.0000012345") << "c" << 0.0000012345 << "1.2345e-6" << "0.0000012345";
|
||||
QTest::newRow("0.00000012345") << "d" << 0.00000012345 << "1.2345e-7" << "1.2345e-7";
|
||||
QTest::newRow("1e20") << "e" << 1e20 << "1e+20" << "100000000000000000000";
|
||||
QTest::newRow("1e21") << "f" << 1e21 << "1e+21" << "1e+21";
|
||||
}
|
||||
|
||||
void tst_qqmlproperty::floatToStringPrecision()
|
||||
{
|
||||
QQmlComponent comp(&engine, testFileUrl("floatToStringPrecision.qml"));
|
||||
QObject *obj = comp.create();
|
||||
QVERIFY(obj != 0);
|
||||
|
||||
QCOMPARE(obj->property("a").toDouble(), 3.4);
|
||||
QCOMPARE(obj->property("a").toString(), QLatin1String("3.4"));
|
||||
QCOMPARE(obj->property("b").toDouble(), 3.4);
|
||||
QCOMPARE(obj->property("b").toString(), QLatin1String("3.4"));
|
||||
QFETCH(QString, propertyName);
|
||||
QFETCH(double, number);
|
||||
QFETCH(QString, qtString);
|
||||
QFETCH(QString, jsString);
|
||||
|
||||
QCOMPARE(obj->property("c").toDouble(), 0.035003945);
|
||||
QCOMPARE(obj->property("c").toString(), QLatin1String("0.035003945"));
|
||||
QCOMPARE(obj->property("d").toDouble(), 0.035003945);
|
||||
QCOMPARE(obj->property("d").toString(), QLatin1String("0.035003945"));
|
||||
const char *name = propertyName.toLatin1().constData();
|
||||
QCOMPARE(obj->property(name).toDouble(), number);
|
||||
QCOMPARE(obj->property(name).toString(), qtString);
|
||||
|
||||
const char *name1 = (propertyName + QLatin1Char('1')).toLatin1().constData();
|
||||
QCOMPARE(obj->property(name1).toDouble(), number);
|
||||
QCOMPARE(obj->property(name1).toString(), qtString);
|
||||
|
||||
const char *name2 = (propertyName + QLatin1Char('2')).toLatin1().constData();
|
||||
QCOMPARE(obj->property(name2).toDouble(), number);
|
||||
QCOMPARE(obj->property(name2).toString(), jsString);
|
||||
|
||||
delete obj;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue