两个浮点无限价值的QCOMPARE

QCOMPARE of two floating-point infinity-values

本文关键字:无限 QCOMPARE 两个      更新时间:2023-10-16
QCOMPARE(
    std::numeric_limits<double>::infinity(),
    std::numeric_limits<double>::infinity());

失败:

Compared doubles are not the same (fuzzy compare)
       Actual   (std::numeric_limits<double>::infinity()): inf
       Expected (std::numeric_limits<double>::infinity()): inf
       Loc: [...]

问题

为什么失败?是否有良好的工作(除了使用QVERIFY之外)?

更新:

我的意思是从测试作者的角度来看。希望提供适当的诊断,并具有无限的实际值。而不是

QCOMPARE(val, std::numeric_limits<double>::infinity());

一个人可以

QVERIFY(val == std::numeric_limits<double>::infinity()))

但是,如果检查失败,则在生成的诊断消息中未显示val的值。看起来像开发人员的主要监督。那么,我必须通过类似于QCOMPARE的精确比较来推出自己的宏?这里有什么建议吗?

此外,很明显,qFuzzyCompare不支持某些角式案例。但是我希望对为什么这种情况有更深入的解释。

在比较浮点和双打的情况下,使用qfuzzycompare()。(http://doc.qt.io/qt-5/qtest.html#qcompare)

基于(http://doc.qt.io/qt-5/qtglobal.html#qfuzzycompare),qt文档自我说,比较无限无效。 - "请注意,比较p1或p2为0.0的值不起作用,也不会比较一个值之一是nan或infinity的值"

我的猜测是,为什么不能比较无限的是,无限的特定值,我的意思是" Infinity-1 "也是无穷大。然后显然比较是一个问题。

解决方法:

如果要比较无穷大,请使用以下函数并比较返回布尔值。

bool qIsInf(double d)

http://doc.qt.io/qt-5/qtglobal.html#qisinf

由于仍然没有工作示例,我在这里发布了自己的宏:

#include <qtestcase.h>
#define COMPARE_DBL(actual, expected, epsilon) 
do {
    if (!QTest::compare_helper((qAbs(actual - expected) <= epsilon), 
                               QString{"Compared values are not the same in respect to epsilon %1"} 
                                    .arg(epsilon).toLocal8Bit().constData(), 
                               QTest::toString(actual), 
                               QTest::toString(expected), 
                               #actual, #expected, __FILE__, __LINE__)) 
        return;
} while (false)

它打印出QT格式格式并正确中断测试用例的错误消息。

我最终写了一个自定义的marco。它模仿QCOMPARE输出,不会突出。

这里(随时重复使用):

inline void isEqualsExactly(
    const double actual,
    const double expected,
    const std::string& actualName,
    const std::string& expectedName)
{
    if(expected == actual)
        return;
    std::stringstream warn;
    const size_t w = std::max(actualName.length(), expectedName.length());
    warn << "Compared values are not the same" << std::endl;
    warn << "   Actual   " << std::setw(w) << std::setfill(' ') << actualName;
    warn << ": " << std::to_string(actual) << std::endl;
    warn << "   Expected " << std::setw(w) << std::setfill(' ') << expectedName;
    warn << ": " << std::to_string(expected);
    QFAIL(warn.str().c_str());
}
#define QCOMPARE_EXACT(actual, expected) 
    isEqualsExactly(actual, expected, #actual, #expected);

用法:

const double val = 0;
const double infinity = std::numeric_limits<double>::infinity();
QCOMPARE_EXACT(val, infinity);

输出:

FAIL!  : TestName Compared values are not the same
   Actual        val: 0.000000
   Expected infinity: inf  
   Loc: [link to location in file]

p.s。我同意,这应该是功能请求。情况很荒谬。如果我要做一个,我将更新帖子。

基于 @thomas-klier的方法,以下宏对我有用:

#define COMPARE_DBL(actual, expected, epsilon) 
do {
    if (!QTest::compare_helper( ((qAbs(actual - expected) <= epsilon) || (actual == expected)), 
        QString{"Compared values are not the same in respect to epsilon %1"} 
             .arg(epsilon).toLocal8Bit().constData(), 
        QTest::toString(actual), 
        QTest::toString(expected), 
        #actual, #expected, __FILE__, __LINE__)) 
        return;
} while (false)