googletest
googletest copied to clipboard
Floating-point values not printed with enough precision
I recently had this failure on a CI platform:
C:/projects/arrow/cpp/src/arrow/util/decimal_test.cc(557): error: Expected equality of these values:
dec.ToReal<Real>(scale)
Which is: 1e-163
expected
Which is: 1e-163
Needless to say, this is not very informative :-) Floating-point values should be printed with enough precision to recreate the exact same values from the string representation, so as to diagnose issues.
If the values were printed as hexfloat as well, the issue would be moot:
C:/projects/arrow/cpp/src/arrow/util/decimal_test.cc(557): error: Expected equality of these values:
dec.ToReal<Real>(scale)
Which is: 1e-163 = 0x1.708d0f84d3de7p-542
expected
Which is: 1e-163 = 0x1.708d0f84d3defp-542
I'm sorry ,but I don't know how to fix this issue.
Here's a solution I once used when a test was strangely failing with values that "seemed" the same (at least according to the EXPECT_EQ() failure printout). I wasn't working with values as tiny as 1e-163 (and I was also working with 32-bit float, not double), but the default EXPECT_EQ() behavior wasn't very helpful, as you can see in my comment...
/* Implement a CUSTOM_EXPECT_EQ macro instead of GoogleTest's standard EXPECT_EQ in order to print more digits for
* floating point failures. E.g. For this EXPECT_EQ(expectedResult, m_measData.voltage[ePhaseA]) failure...
* Expected equality of these values:
* expectedResult
* Which is: 0.0726339
* m_measData.voltage[ePhaseA]
* Which is: 0.0726339
* ...(note that expected & actual are rounded and appear the same!), with CUSTOM_EXPECT_EQ, we would see this instead:
* Expected equality of these values:
* expectedResult
* Which is: 0.072633899748325348
* m_measData.voltage[ePhaseA]
* Which is: 0.072633907198905945
*/
#define CUSTOM_EXPECT_EQ(expected,actual) EXPECT_PRED_FORMAT2(floatEqPred, expected, actual)
testing::AssertionResult floatEqPred(char const* expectedFmt, char const* actualFmt, float32_t expected, float32_t actual)
{
return (expected == actual)
? testing::AssertionSuccess()
: testing::AssertionFailure() << "Expected equality of these values:\n "
<< expectedFmt << "\n Which is: " << expected << "\n "
<< actualFmt << "\n Which is: " << actual << "\n";
}
@phonetagger: Yup, the only robust solution here is hexfloat printing.
@NAThompson Are you saying there's no robust solution that prints floating point values in easy-to-interpret decimal? Most people wouldn't be happy to have to convert from hexfloat to a format they can actually work with.
AFAIK, printing with enough precision is implemented by a bunch of open source libraries, including Google's own double-precision.
Most people wouldn't be happy to have to convert from hexfloat to a format they can actually work with.
Just print both formats.
Diff to fix:
diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h
index 04a84f32..02fb4d36 100644
--- a/googletest/include/gtest/gtest.h
+++ b/googletest/include/gtest/gtest.h
@@ -1572,11 +1572,11 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
::std::stringstream lhs_ss;
lhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
- << lhs_value;
+ << lhs_value << " = " << std::hexfloat << lhs_value;
::std::stringstream rhs_ss;
rhs_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
- << rhs_value;
+ << rhs_value << " = " << std::hexfloat << lhs_value;
return EqFailure(lhs_expression, rhs_expression,
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),