From 3f936e9094f3a6e4d76791c1eff7ae92f91b61ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 13 Nov 2012 19:17:17 +0100 Subject: Fixes problem with single precision floats in QDataStream (Windows). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the floating-point behavior in MSVC is set to "precise" (default), assigning nan numbers to a float causes the bit pattern to be altered (only affects 32bit builds). We should therefore not assign the swapped value back to a float and use it. Task-number: QTBUG-25950 Change-Id: I7b6cc4d546e5c8aeafdede749056358b7d639ec7 Reviewed-by: Jędrzej Nowacki --- .../corelib/io/qdatastream/tst_qdatastream.cpp | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'tests/auto/corelib') diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index ef384f86cd..f999f44670 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -195,6 +195,8 @@ private slots: void compatibility_Qt3(); void compatibility_Qt2(); + void floatingPointNaN(); + private: void writebool(QDataStream *s); void writeQBitArray(QDataStream *s); @@ -3102,6 +3104,48 @@ void tst_QDataStream::compatibility_Qt2() QVERIFY(in_palette.color(QPalette::Light) == Qt::green); } +void tst_QDataStream::floatingPointNaN() +{ + QDataStream::ByteOrder bo = QSysInfo::ByteOrder == QSysInfo::BigEndian + ? QDataStream::LittleEndian + : QDataStream::BigEndian; + + // Test and verify that values that become (s)nan's after swapping endianness + // don't change in the process. + // When compiling with e.g., MSVC (32bit) and when the fpu is used (fp:precise) + // all snan's will be converted to qnan's (default behavior). + // IF we get a snan after swapping endianness we can not copy the value to another + // float as this will cause the value to differ from the original value. + QByteArray ba; + + union { + float f; + quint32 i; + } xs[2]; + + xs[0].i = qbswap(0xff800001); + xs[1].i = qbswap(0x7f800001); + + { + QDataStream stream(&ba, QIODevice::WriteOnly); + stream.setByteOrder(bo); + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + stream << xs[0].f; + stream << xs[1].f; + } + + { + QDataStream stream(ba); + stream.setByteOrder(bo); + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + float fr = 0.0f; + stream >> fr; + QCOMPARE(fr, xs[0].f); + stream >> fr; + QCOMPARE(fr, xs[1].f); + } +} + void tst_QDataStream::floatingPointPrecision() { QByteArray ba; -- cgit v1.2.3