diff options
Diffstat (limited to 'tests/auto/corelib/kernel/qmath/tst_qmath.cpp')
-rw-r--r-- | tests/auto/corelib/kernel/qmath/tst_qmath.cpp | 119 |
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() |