summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/kernel/qmath/tst_qmath.cpp')
-rw-r--r--tests/auto/corelib/kernel/qmath/tst_qmath.cpp119
1 files changed, 79 insertions, 40 deletions
diff --git a/tests/auto/corelib/kernel/qmath/tst_qmath.cpp b/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
index 5496daf269..1961b71d83 100644
--- a/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
+++ b/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <qmath.h>
+#include <qfloat16.h>
class tst_QMath : public QObject
{
@@ -41,6 +17,7 @@ private slots:
void radiansToDegrees();
void trigonometry_data();
void trigonometry();
+ void hypotenuse();
void funcs_data();
void funcs();
void qNextPowerOfTwo32S_data();
@@ -152,7 +129,7 @@ void tst_QMath::trigonometry()
QFETCH(const double, x);
QFETCH(const double, y);
QFETCH(const double, angle);
- const double hypot = std::hypot(x, y);
+ const double hypot = qHypot(x, y);
QVERIFY(hypot > 0);
QCOMPARE(qAtan2(y, x), angle);
QCOMPARE(qSin(angle), y / hypot);
@@ -167,6 +144,79 @@ void tst_QMath::trigonometry()
}
}
+void tst_QMath::hypotenuse()
+{
+ // Correct return-types, particularly when qfloat16 is involved:
+ static_assert(std::is_same<decltype(qHypot(qfloat16(1), qfloat16(1), qfloat16(1),
+ qfloat16(1), qfloat16(1), qfloat16(1),
+ qfloat16(1), qfloat16(1), qfloat16(1))),
+ qfloat16>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), qfloat16(4), qfloat16(12))),
+ qfloat16>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), qfloat16(4), 12.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0f, qfloat16(12))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, qfloat16(4), qfloat16(12))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0f, 12.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, qfloat16(4), 12.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0f, qfloat16(12))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), qfloat16(4))), qfloat16>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, qfloat16(4))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, qfloat16(4))), double>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, qfloat16(4))), double>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0L)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0L, qfloat16(4))), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0L)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4.0f)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, 4.0f)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0L, 4.0f)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4.0L)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0L, 4.0)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, 4)), double>::value);
+
+ // Works for all numeric types:
+ QCOMPARE(qHypot(3, 4), 5);
+ QCOMPARE(qHypot(qfloat16(5), qfloat16(12)), qfloat16(13));
+ QCOMPARE(qHypot(3.0f, 4.0f, 12.0f), 13.0f);
+ QCOMPARE(qHypot(3.0, 4.0, 12.0, 84.0), 85.0);
+ QCOMPARE(qHypot(3.0f, 4.0f, 12.0f, 84.0f, 720.0f), 725.0f);
+ QCOMPARE(qHypot(3.0, 4.0, 12.0, 84.0, 3612.0), 3613.0);
+ // Integral gets promoted to double:
+ QCOMPARE(qHypot(1, 1), M_SQRT2);
+ // Caller can mix types freely:
+ QCOMPARE(qHypot(3.0f, 4, 12.0, 84.0f, qfloat16(720), 10500), 10525);
+ // NaN wins over any finite:
+ QCOMPARE(qHypot(3, 4.0, 12.0f, qQNaN()), qQNaN());
+ QCOMPARE(qHypot(3, 4.0, qQNaN(), 12.0f), qQNaN());
+ QCOMPARE(qHypot(3, qQNaN(), 4.0, 12.0f), qQNaN());
+ QCOMPARE(qHypot(qQNaN(), 3, 4.0, 12.0f), qQNaN());
+ // but Infinity beats NaN:
+ QCOMPARE(qHypot(3, 4.0f, -qInf(), qQNaN()), qInf());
+ QCOMPARE(qHypot(3, -qInf(), 4.0f, qQNaN()), qInf());
+ QCOMPARE(qHypot(-qInf(), 3, 4.0f, qQNaN()), qInf());
+ QCOMPARE(qHypot(qQNaN(), 3, -qInf(), 4.0f), qInf());
+ QCOMPARE(qHypot(3, qQNaN(), 4.0f, -qInf()), qInf());
+ QCOMPARE(qHypot(3, 4.0f, qQNaN(), -qInf()), qInf());
+ // Components whose squares sum to zero don't change the end result:
+ const double minD = std::numeric_limits<double>::min();
+ QVERIFY(minD * minD + minD * minD == 0); // *NOT* QCOMPARE
+ QCOMPARE(qHypot(minD, minD, 12.0), 12.0);
+ const float minF = std::numeric_limits<float>::min();
+ QVERIFY(minF * minF + minF * minF == 0.0f); // *NOT* QCOMPARE
+ QCOMPARE(qHypot(minF, minF, 12.0f), 12.0f);
+ const qfloat16 minF16 = std::numeric_limits<qfloat16>::min();
+ QVERIFY(minF16 * minF16 + minF16 * minF16 == qfloat16(0)); // *NOT* QCOMPARE
+ QCOMPARE(qHypot(minF16, minF16, qfloat16(12)), qfloat16(12));
+}
+
void tst_QMath::funcs_data()
{
QTest::addColumn<double>("value");
@@ -215,9 +265,6 @@ void tst_QMath::qNextPowerOfTwo32S_data()
QTest::newRow("2^30") << (1 << 30) << (1U << 31);
QTest::newRow("2^30 + 1") << (1 << 30) + 1 << (1U << 31);
QTest::newRow("2^31 - 1") << 0x7FFFFFFF << (1U<<31);
- QTest::newRow("-1") << -1 << 0U;
- QTest::newRow("-128") << -128 << 0U;
- QTest::newRow("-(2^31)") << int(0x80000000) << 0U;
}
void tst_QMath::qNextPowerOfTwo32S()
@@ -243,8 +290,6 @@ void tst_QMath::qNextPowerOfTwo32U_data()
QTest::newRow("2^30") << (1U << 30) << (1U << 31);
QTest::newRow("2^30 + 1") << (1U << 30) + 1 << (1U << 31);
QTest::newRow("2^31 - 1") << 2147483647U << 2147483648U;
- QTest::newRow("2^31") << 2147483648U << 0U;
- QTest::newRow("2^31 + 1") << 2147483649U << 0U;
}
void tst_QMath::qNextPowerOfTwo32U()
@@ -271,10 +316,6 @@ void tst_QMath::qNextPowerOfTwo64S_data()
QTest::newRow("2^31") << Q_INT64_C(2147483648) << Q_UINT64_C(0x100000000);
QTest::newRow("2^31 + 1") << Q_INT64_C(2147483649) << Q_UINT64_C(0x100000000);
QTest::newRow("2^63 - 1") << Q_INT64_C(0x7FFFFFFFFFFFFFFF) << Q_UINT64_C(0x8000000000000000);
- QTest::newRow("-1") << Q_INT64_C(-1) << Q_UINT64_C(0);
- QTest::newRow("-128") << Q_INT64_C(-128) << Q_UINT64_C(0);
- QTest::newRow("-(2^31)") << -Q_INT64_C(0x80000000) << Q_UINT64_C(0);
- QTest::newRow("-(2^63)") << (qint64)Q_INT64_C(0x8000000000000000) << Q_UINT64_C(0);
}
void tst_QMath::qNextPowerOfTwo64S()
@@ -298,8 +339,6 @@ void tst_QMath::qNextPowerOfTwo64U_data()
QTest::newRow("65535") << Q_UINT64_C(65535) << Q_UINT64_C(65536);
QTest::newRow("65536") << Q_UINT64_C(65536) << Q_UINT64_C(131072);
QTest::newRow("2^63 - 1") << Q_UINT64_C(0x7FFFFFFFFFFFFFFF) << Q_UINT64_C(0x8000000000000000);
- QTest::newRow("2^63") << Q_UINT64_C(0x8000000000000000) << Q_UINT64_C(0);
- QTest::newRow("2^63 + 1") << Q_UINT64_C(0x8000000000000001) << Q_UINT64_C(0);
}
void tst_QMath::qNextPowerOfTwo64U()