I'm seeing failures of an EXPECT_EQ for 32-bit float comparisons that look very odd:
RawDataConverter_Test.cpp:325: Failure
Expected equality of these values:
expectedResult
Which is: 0.0726339
actualResult
Which is: 0.0726339
I know that floating point computations performed two different ways that "mathematically ought to produce the same results" often don't produce exactly the same results due to rounding of intermediate terms (which is why GoogleTest recommends using EXPECT_FLOAT_EQ, EXPECT_DOUBLE_EQ, or EXPECT_NEAR for floating point tests), but that's not my issue here. Both of my "ways of computing" the result are deterministically identical, so they should always produce the same result; if they don't, then someone may have bungled a code change in the production version of the code.
The numbers above look the same to me, so it seemed odd that the EXPECT_EQ would fail. Then I added my own printf of the values before the EXPECT_EQ:
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);
...and now I see this:
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
Now it's clear why the EXPECT_EQ failed, but it would be nice if GoogleTest's EXPECT_EQ failure output for float comparisons showed sufficient precision in the first place.
I know you can customize GoogleTest failure output to print custom strings for your own classes by providing a PrintTo() function or an overload of std::ostream& operator<<(std::ostream&, const T&), but is there a way to provide a custom PrintTo() or operator<<() for builtin types like float? Or is there any other way to make GoogleTest print float with greater precision than normal?
I tried doing that...
namespace testing
{
void PrintTo(const float value, std::ostream* os)
{
std::streamsize oldPrecision = os->precision();
os->precision(12);
*os << value;
os->precision(oldPrecision);
}
}
...(with and without the namespace testing {}), but it was never called. I also tried...
// (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;
}
...but that doesn't compile for the error reason shown in the comment.
BTW I am using GoogleTest release 1.10.0, released 03 October 2019.