diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-29 12:11:35 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-09-06 12:35:12 +0200 |
commit | d3ff95dcb84861e8f42b480910d822b4ca8715b1 (patch) | |
tree | 7ade0148126e83ed589258983b632fbe3488d7fb /tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp | |
parent | a0e0b51001edfc1c7aea113c472ce995efa833fd (diff) |
Round float->qfloat16 to even
Calibrated to match F16C and ARM-FP16 hardware conversions.
Change-Id: I3bdd4d3db3046fee4aeb24e4ce8b9bc9a06e0397
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp')
-rw-r--r-- | tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 20d8a1d895..82ad6b1c38 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -32,6 +32,10 @@ #include <math.h> +//#define DO_FULL_TEST + +static_assert(sizeof(float) == sizeof(quint32), "Float not 32-bit"); + class tst_qfloat16: public QObject { Q_OBJECT @@ -48,6 +52,11 @@ private slots: void promotionTests(); void arithOps_data(); void arithOps(); +#if defined DO_FULL_TEST + void floatToFloat16Full_data(); + void floatToFloat16Full(); + void floatFromFloat16Full(); +#endif void floatToFloat16(); void floatFromFloat16(); void finite_data(); @@ -344,6 +353,63 @@ void tst_qfloat16::arithOps() QVERIFY(qFuzzyCompare(r4,1.f/val2)); } +#if defined DO_FULL_TEST +void tst_qfloat16::floatToFloat16Full_data() +{ + QTest::addColumn<quint32>("group"); + for (quint32 j = 0x00; j < 0x100; ++j) + QTest::addRow("%02x", j) << j; + +} + +void tst_qfloat16::floatToFloat16Full() +{ + QFETCH(quint32, group); + for (quint32 j = 0x00; j < 0x100; ++j) { + quint32 data[1<<16]; + qfloat16 out[1<<16]; + qfloat16 expected[1<<16]; + float in[1<<16]; + + for (int i = 0; i < (1<<16); ++i) + data[i] = (group << 24) | (j << 16) | i; + + memcpy(in, data, (1<<16)*sizeof(float)); + + for (int i = 0; i < (1<<16); ++i) + expected[i] = qfloat16(in[i]); + + qFloatToFloat16(out, in, 1<<16); + + for (int i = 0; i < (1<<16); ++i) { + if (out[i] != expected[i]) + QVERIFY(qIsNaN(out[i]) && qIsNaN(expected[i])); + } + } +} + +void tst_qfloat16::floatFromFloat16Full() +{ + quint16 data[1<<16]; + float out[1<<16]; + float expected[1<<16]; + + for (int i = 0; i < (1<<16); ++i) + data[i] = i; + + const qfloat16 *in = reinterpret_cast<const qfloat16 *>(data); + + for (int i = 0; i < (1<<16); ++i) + expected[i] = float(in[i]); + + qFloatFromFloat16(out, in, 1<<16); + + for (int i = 0; i < (1<<16); ++i) + if (out[i] != expected[i]) + QVERIFY(qIsNaN(out[i]) && qIsNaN(expected[i])); +} +#endif + void tst_qfloat16::floatToFloat16() { constexpr int count = 10000; @@ -505,8 +571,8 @@ void tst_qfloat16::limits() // See also: qNaN() and infinity() QCOMPARE(qFpClassify(high10), FP_NORMAL); // How many digits are significant ? (Casts avoid linker errors ...) - QCOMPARE(int(Bounds::digits10), 3); // ~9.78e-4 has enough sigificant digits: - qfloat16 below(9.781e-4f), above(9.789e-4f); // both round to ~9.785e-4 + QCOMPARE(int(Bounds::digits10), 3); // ~9.88e-4 has enough sigificant digits: + qfloat16 below(9.876e-4f), above(9.884e-4f); // both round to ~9.88e-4 QVERIFY(below == above); QCOMPARE(int(Bounds::max_digits10), 5); // we need 5 to distinguish these two: QVERIFY(qfloat16(1000.5f) != qfloat16(1001.4f)); |