【问题标题】:GoogleTest: Increase precision of EXPECT_EQ float failuresGoogleTest:提高 EXPECT_EQ 浮动失败的精度
【发布时间】:2022-06-10 22:32:56
【问题描述】:

我看到 EXPECT_EQ 的 32 位浮点比较失败,看起来很奇怪:

RawDataConverter_Test.cpp:325: Failure
Expected equality of these values:
  expectedResult
Which is: 0.0726339
  actualResult
Which is: 0.0726339

我知道浮点计算执行两种不同的方式,“数学上应该产生相同的结果”由于中间项的舍入,通常不会产生完全相同的结果(这就是为什么 GoogleTest recommends using EXPECT_FLOAT_EQ, EXPECT_DOUBLE_EQ, or EXPECT_NEAR 用于浮点测试),但这不是我的问题。我的两种“计算方式”结果在确定性上是相同的,所以它们应该总是产生相同的结果;如果他们不这样做,那么可能有人在代码的生产版本中搞砸了代码更改。

上面的数字在我看来是一样的,所以 EXPECT_EQ 失败似乎很奇怪。然后我在EXPECT_EQ 之前添加了我自己的printf 值:

        float expectedResult = ...
        float actualResult = ...

        printf("\nexp=%0.20f (0x%08x)\nact=%0.20f (0x%08x) (%s)\n",
               expectedResult,
               expectedResultU32,
               actualResult,
               actualResultU32,
               (expectedResult == actualResult) ? "same" : "diff");
        EXPECT_EQ(expectedResult, actualResult);

...现在我看到了:

exp=0.07263389974832534800 (0x3d94c115)
act=0.07263390719890594500 (0x3d94c116) (diff)
RawDataConverter_Test.cpp:325: Failure
Expected equality of these values:
  expectedResult
Which is: 0.0726339
  actualResult
Which is: 0.0726339

现在很清楚为什么 EXPECT_EQ 失败了,但如果 GoogleTest 的 float 比较的 EXPECT_EQ 失败输出首先显示足够的精度,那就太好了。

我知道您可以通过提供PrintTo() 函数或std::ostream& operator<<(std::ostream&, const T&) 的重载来为您自己的类打印自定义字符串customize GoogleTest failure output,但是有没有办法为您提供自定义PrintTo()operator<<()float这样的内置类型?或者有没有其他方法可以让 GoogleTest 打印 float 的精度高于正常水平?

我试过这样做...

namespace testing
{
   void PrintTo(const float value, std::ostream* os)
   {
      std::streamsize oldPrecision = os->precision();
      os->precision(12);
      *os << value;
      os->precision(oldPrecision);
   }
}

...(有和没有namespace testing {}),但它从未被调用过。我也试过...

// (same error if 2nd argument is ------>  const float &value)
std::ostream& operator<<(std::ostream& os, const float value)
{
   std::streamsize oldPrecision = os.precision();
   os.precision(12);
   os << value;   // <------- error: ambiguous overload for 'operator<<'
   os.precision(oldPrecision);
   return os;
}

...但由于注释中显示的错误原因,它无法编译。

【问题讨论】:

  • == 用于浮点数并不是一个好主意,如果您需要控制精度,为什么不使用EXPECT_NEAR 呢?
  • @Quimby 我几乎在我的问题中添加了一些内容,说我知道这一点,这不是问题,但我没有这样做,抱歉遗漏了。我担心的是我希望 GoogleTest 失败消息的输出具有足够的精度来观察两个浮点数是否完全相同。
  • 哦,好吧,这是个好问题,但我不知道答案,对不起。
  • 视觉差异这么重要吗?难道你不能记住,如果你看到相同的浮点数彼此不相等,那么最后一个数字肯定是±1。我们在学校研究过,浮点数0.0726339表示区间[0.07263385, 0.07263395)内的任意实数。
  • @273K 对于按照严格的 IEEE754 实现的特定数值算法类别,精确到最后一位实际上是有意义的,而且不仅仅是“视觉差异”。以高精度查看特定错误对于确定计算可能在何处引入此类错误很有用。我也很想知道除了手动打印之外是否还有一个方便的答案 - 我已经完成了精确的数字内容和 googletest,但还没有同时完成这两个。

标签: c++ googletest


猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多