mirror of
https://github.com/google/googletest.git
synced 2024-12-26 17:41:03 +08:00
When printing floating-point numbers, print full precision by default.
To make debug output readable, we still use the faster 6-digit precision sometimes, but only if it will round-trip. This way, when a test fails due to a very small difference in floating-point numbers, users will have enough digits to see the difference. PiperOrigin-RevId: 488958311 Change-Id: Ibcac43f48a97006d89217530c69386cc4fa2735c
This commit is contained in:
parent
4408a0288b
commit
9c332145b7
@ -484,6 +484,81 @@ GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
|
||||
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
|
||||
#endif // __SIZEOF_INT128__
|
||||
|
||||
// The default resolution used to print floating-point values uses only
|
||||
// 6 digits, which can be confusing if a test compares two values whose
|
||||
// difference lies in the 7th digit. So we'd like to print out numbers
|
||||
// in full precision.
|
||||
// However if the value is something simple like 1.1, full will print a
|
||||
// long string like 1.100000001 due to floating-point numbers not using
|
||||
// a base of 10. This routiune returns an appropriate resolution for a
|
||||
// given floating-point number, that is, 6 if it will be accurate, or a
|
||||
// max_digits10 value (full precision) if it won't, for values between
|
||||
// 0.0001 and one million.
|
||||
// It does this by computing what those digits would be (by multiplying
|
||||
// by an appropriate power of 10), then dividing by that power again to
|
||||
// see if gets the original value back.
|
||||
// A similar algorithm applies for values larger than one million; note
|
||||
// that for those values, we must divide to get a six-digit number, and
|
||||
// then multiply to possibly get the original value again.
|
||||
template <typename FloatType>
|
||||
int AppropriateResolution(FloatType val) {
|
||||
int full = std::numeric_limits<FloatType>::max_digits10;
|
||||
if (val < 0) val = -val;
|
||||
|
||||
if (val < 1000000) {
|
||||
FloatType mulfor6 = 1e10;
|
||||
if (val >= 100000.0) { // 100,000 to 999,999
|
||||
mulfor6 = 1.0;
|
||||
} else if (val >= 10000.0) {
|
||||
mulfor6 = 1e1;
|
||||
} else if (val >= 1000.0) {
|
||||
mulfor6 = 1e2;
|
||||
} else if (val >= 100.0) {
|
||||
mulfor6 = 1e3;
|
||||
} else if (val >= 10.0) {
|
||||
mulfor6 = 1e4;
|
||||
} else if (val >= 1.0) {
|
||||
mulfor6 = 1e5;
|
||||
} else if (val >= 0.1) {
|
||||
mulfor6 = 1e6;
|
||||
} else if (val >= 0.01) {
|
||||
mulfor6 = 1e7;
|
||||
} else if (val >= 0.001) {
|
||||
mulfor6 = 1e8;
|
||||
} else if (val >= 0.0001) {
|
||||
mulfor6 = 1e9;
|
||||
}
|
||||
if (static_cast<int32_t>(val * mulfor6 + 0.5) / mulfor6 == val) return 6;
|
||||
} else if (val < 1e10) {
|
||||
FloatType divfor6 = 1.0;
|
||||
if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999
|
||||
divfor6 = 10000;
|
||||
} else if (val >= 1e8) { // 100,000,000 to 999,999,999
|
||||
divfor6 = 1000;
|
||||
} else if (val >= 1e7) { // 10,000,000 to 99,999,999
|
||||
divfor6 = 100;
|
||||
} else if (val >= 1e6) { // 1,000,000 to 9,999,999
|
||||
divfor6 = 10;
|
||||
}
|
||||
if (static_cast<int32_t>(val / divfor6 + 0.5) * divfor6 == val) return 6;
|
||||
}
|
||||
return full;
|
||||
}
|
||||
|
||||
inline void PrintTo(float f, ::std::ostream* os) {
|
||||
auto old_precision = os->precision();
|
||||
os->precision(AppropriateResolution(f));
|
||||
*os << f;
|
||||
os->precision(old_precision);
|
||||
}
|
||||
|
||||
inline void PrintTo(double d, ::std::ostream* os) {
|
||||
auto old_precision = os->precision();
|
||||
os->precision(AppropriateResolution(d));
|
||||
*os << d;
|
||||
os->precision(old_precision);
|
||||
}
|
||||
|
||||
// Overloads for C strings.
|
||||
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
|
@ -458,7 +458,15 @@ TEST(PrintBuiltInTypeTest, Int128) {
|
||||
|
||||
// Floating-points.
|
||||
TEST(PrintBuiltInTypeTest, FloatingPoints) {
|
||||
EXPECT_EQ("1.5", Print(1.5f)); // float
|
||||
// float (32-bit precision)
|
||||
EXPECT_EQ("1.5", Print(1.5f));
|
||||
|
||||
EXPECT_EQ("1.0999999", Print(1.09999990f));
|
||||
EXPECT_EQ("1.1", Print(1.10000002f));
|
||||
EXPECT_EQ("1.10000014", Print(1.10000014f));
|
||||
EXPECT_EQ("9e+09", Print(9e9f));
|
||||
|
||||
// double
|
||||
EXPECT_EQ("-2.5", Print(-2.5)); // double
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user