QtCore: fix the number precision in QJsonDocument.toJson() again
Need to store 17 decimal digits for binary64, IEEE 754 double formats. Autotest is included. Test cases from TC39 test suite for ECMAScript. Task-number: QTBUG-31926 Change-Id: I546398f21ea7ff5e40e89fc9de8703f628f55df9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
This commit is contained in:
parent
6e8dddadd8
commit
94c8efff8a
@ -170,7 +170,7 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
|
||||
json += v.toBoolean() ? "true" : "false";
|
||||
break;
|
||||
case QJsonValue::Double:
|
||||
json += QByteArray::number(v.toDouble(b), 'g', 13);
|
||||
json += QByteArray::number(v.toDouble(b), 'g', 17);
|
||||
break;
|
||||
case QJsonValue::String:
|
||||
json += '"';
|
||||
|
@ -40,6 +40,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
#include "qjsonarray.h"
|
||||
#include "qjsonobject.h"
|
||||
#include "qjsonvalue.h"
|
||||
@ -62,6 +63,8 @@ private Q_SLOTS:
|
||||
|
||||
void testValueSimple();
|
||||
void testNumbers();
|
||||
void testNumbers_2();
|
||||
void testNumbers_3();
|
||||
|
||||
void testObjectSimple();
|
||||
void testObjectSmallKeys();
|
||||
@ -329,6 +332,65 @@ void tst_QtJson::testNumbers()
|
||||
|
||||
}
|
||||
|
||||
void tst_QtJson::testNumbers_2()
|
||||
{
|
||||
// test cases from TC39 test suite for ECMAScript
|
||||
// http://hg.ecmascript.org/tests/test262/file/d067d2f0ca30/test/suite/ch08/8.5/8.5.1.js
|
||||
|
||||
// Fill an array with 2 to the power of (0 ... -1075)
|
||||
double value = 1;
|
||||
double floatValues[1076], floatValues_1[1076];
|
||||
QJsonObject jObject;
|
||||
for (int power = 0; power <= 1075; power++) {
|
||||
floatValues[power] = value;
|
||||
jObject.insert(QString::number(power), QJsonValue(floatValues[power]));
|
||||
// Use basic math operations for testing, which are required to support 'gradual underflow' rather
|
||||
// than Math.pow etc..., which are defined as 'implementation dependent'.
|
||||
value = value * 0.5;
|
||||
}
|
||||
|
||||
QJsonDocument jDocument1(jObject);
|
||||
QByteArray ba(jDocument1.toJson());
|
||||
|
||||
QJsonDocument jDocument2(QJsonDocument::fromJson(ba));
|
||||
for (int power = 0; power <= 1075; power++) {
|
||||
floatValues_1[power] = jDocument2.object().value(QString::number(power)).toDouble();
|
||||
QVERIFY2(floatValues[power] == floatValues_1[power], QString("floatValues[%1] != floatValues_1[%1]").arg(power).toLatin1());
|
||||
}
|
||||
|
||||
// The last value is below min denorm and should round to 0, everything else should contain a value
|
||||
QVERIFY2(floatValues_1[1075] == 0, "Value after min denorm should round to 0");
|
||||
|
||||
// Validate the last actual value is min denorm
|
||||
QVERIFY2(floatValues_1[1074] == 4.9406564584124654417656879286822e-324, QString("Min denorm value is incorrect: %1").arg(floatValues_1[1074]).toLatin1());
|
||||
|
||||
// Validate that every value is half the value before it up to 1
|
||||
for (int index = 1074; index > 0; index--) {
|
||||
QVERIFY2(floatValues_1[index] != 0, QString("2**- %1 should not be 0").arg(index).toLatin1());
|
||||
|
||||
QVERIFY2(floatValues_1[index - 1] == (floatValues_1[index] * 2), QString("Value should be double adjacent value at index %1").arg(index).toLatin1());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QtJson::testNumbers_3()
|
||||
{
|
||||
// test case from QTBUG-31926
|
||||
double d1 = 1.123451234512345;
|
||||
double d2 = 1.123451234512346;
|
||||
|
||||
QJsonObject jObject;
|
||||
jObject.insert("d1", QJsonValue(d1));
|
||||
jObject.insert("d2", QJsonValue(d2));
|
||||
QJsonDocument jDocument1(jObject);
|
||||
QByteArray ba(jDocument1.toJson());
|
||||
|
||||
QJsonDocument jDocument2(QJsonDocument::fromJson(ba));
|
||||
|
||||
double d1_1(jDocument2.object().value("d1").toDouble());
|
||||
double d2_1(jDocument2.object().value("d2").toDouble());
|
||||
QVERIFY(d1_1 != d2_1);
|
||||
}
|
||||
|
||||
void tst_QtJson::testObjectSimple()
|
||||
{
|
||||
QJsonObject object;
|
||||
|
Loading…
Reference in New Issue
Block a user