Skip to content

Commit 62df7bd

Browse files
Abseil Teamcopybara-github
authored andcommitted
This change adjusts how ASSERT_NEAR and EXPECT_NEAR treats infinity, such that ASSERT_NEAR(inf, inf, 0) passes. This makes the behavior more consistent with ASSERT_EQ(inf, inf) which succeeds.
Some examples of asserts that now pass: ``` ASSERT_NEAR(inf, inf, 0) ASSERT_NEAR(-inf, inf, inf) ASSERT_NEAR(inf, x, inf) // x is any finite floating point value ``` PiperOrigin-RevId: 685748133 Change-Id: I7b3af377773e8e0031e4c6b86830cbbf76bf20c6
1 parent 71815bb commit 62df7bd

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

docs/reference/assertions.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,15 +276,17 @@ Units in the Last Place (ULPs). To learn more about ULPs, see the article
276276
`ASSERT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)`
277277
278278
Verifies that the two `float` values *`val1`* and *`val2`* are approximately
279-
equal, to within 4 ULPs from each other.
279+
equal, to within 4 ULPs from each other. Infinity and the largest finite float
280+
value are considered to be one ULP apart.
280281
281282
### EXPECT_DOUBLE_EQ {#EXPECT_DOUBLE_EQ}
282283
283284
`EXPECT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)` \
284285
`ASSERT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)`
285286
286287
Verifies that the two `double` values *`val1`* and *`val2`* are approximately
287-
equal, to within 4 ULPs from each other.
288+
equal, to within 4 ULPs from each other. Infinity and the largest finite double
289+
value are considered to be one ULP apart.
288290
289291
### EXPECT_NEAR {#EXPECT_NEAR}
290292
@@ -294,6 +296,11 @@ equal, to within 4 ULPs from each other.
294296
Verifies that the difference between *`val1`* and *`val2`* does not exceed the
295297
absolute error bound *`abs_error`*.
296298
299+
If *`val`* and *`val2`* are both infinity of the same sign, the difference is
300+
considered to be 0. Otherwise, if either value is infinity, the difference is
301+
considered to be infinity. All non-NaN values (including infinity) are
302+
considered to not exceed an *`abs_error`* of infinity.
303+
297304
## Exception Assertions {#exceptions}
298305
299306
The following assertions verify that a piece of code throws, or does not throw,

googletest/src/gtest.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1660,10 +1660,25 @@ std::string GetBoolAssertionFailureMessage(
16601660
return msg.GetString();
16611661
}
16621662

1663-
// Helper function for implementing ASSERT_NEAR.
1663+
// Helper function for implementing ASSERT_NEAR. Treats infinity as a specific
1664+
// value, such that comparing infinity to infinity is equal, the distance
1665+
// between -infinity and +infinity is infinity, and infinity <= infinity is
1666+
// true.
16641667
AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2,
16651668
const char* abs_error_expr, double val1,
16661669
double val2, double abs_error) {
1670+
// We want to return success when the two values are infinity and at least
1671+
// one of the following is true:
1672+
// * The values are the same-signed infinity.
1673+
// * The error limit itself is infinity.
1674+
// This is done here so that we don't end up with a NaN when calculating the
1675+
// difference in values.
1676+
if (std::isinf(val1) && std::isinf(val2) &&
1677+
(std::signbit(val1) == std::signbit(val2) ||
1678+
(abs_error > 0.0 && std::isinf(abs_error)))) {
1679+
return AssertionSuccess();
1680+
}
1681+
16671682
const double diff = fabs(val1 - val2);
16681683
if (diff <= abs_error) return AssertionSuccess();
16691684

googletest/test/gtest_unittest.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,6 +2870,8 @@ TEST_F(FloatTest, LargeDiff) {
28702870
// This ensures that no overflow occurs when comparing numbers whose
28712871
// absolute value is very large.
28722872
TEST_F(FloatTest, Infinity) {
2873+
EXPECT_FLOAT_EQ(values_.infinity, values_.infinity);
2874+
EXPECT_FLOAT_EQ(-values_.infinity, -values_.infinity);
28732875
EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity);
28742876
EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity);
28752877
EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity),
@@ -2894,6 +2896,11 @@ TEST_F(FloatTest, NaN) {
28942896
EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1), "v.nan1");
28952897
EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2), "v.nan2");
28962898
EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1), "v.nan1");
2899+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, v.nan1, 1.0f), "v.nan1");
2900+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, v.nan1, v.infinity), "v.nan1");
2901+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, 1.0f), "v.nan1");
2902+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, v.infinity),
2903+
"v.nan1");
28972904

28982905
EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity), "v.infinity");
28992906
}
@@ -2917,11 +2924,28 @@ TEST_F(FloatTest, Commutative) {
29172924

29182925
// Tests EXPECT_NEAR.
29192926
TEST_F(FloatTest, EXPECT_NEAR) {
2927+
static const FloatTest::TestValues& v = this->values_;
2928+
29202929
EXPECT_NEAR(-1.0f, -1.1f, 0.2f);
29212930
EXPECT_NEAR(2.0f, 3.0f, 1.0f);
2931+
EXPECT_NEAR(v.infinity, v.infinity, 0.0f);
2932+
EXPECT_NEAR(-v.infinity, -v.infinity, 0.0f);
2933+
EXPECT_NEAR(0.0f, 1.0f, v.infinity);
2934+
EXPECT_NEAR(v.infinity, -v.infinity, v.infinity);
2935+
EXPECT_NEAR(-v.infinity, v.infinity, v.infinity);
29222936
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f, 1.5f, 0.25f), // NOLINT
29232937
"The difference between 1.0f and 1.5f is 0.5, "
29242938
"which exceeds 0.25f");
2939+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, -v.infinity, 0.0f), // NOLINT
2940+
"The difference between v.infinity and -v.infinity "
2941+
"is inf, which exceeds 0.0f");
2942+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(-v.infinity, v.infinity, 0.0f), // NOLINT
2943+
"The difference between -v.infinity and v.infinity "
2944+
"is inf, which exceeds 0.0f");
2945+
EXPECT_NONFATAL_FAILURE(
2946+
EXPECT_NEAR(v.infinity, v.close_to_infinity, v.further_from_infinity),
2947+
"The difference between v.infinity and v.close_to_infinity is inf, which "
2948+
"exceeds v.further_from_infinity");
29252949
}
29262950

29272951
// Tests ASSERT_NEAR.
@@ -3028,6 +3052,8 @@ TEST_F(DoubleTest, LargeDiff) {
30283052
// This ensures that no overflow occurs when comparing numbers whose
30293053
// absolute value is very large.
30303054
TEST_F(DoubleTest, Infinity) {
3055+
EXPECT_DOUBLE_EQ(values_.infinity, values_.infinity);
3056+
EXPECT_DOUBLE_EQ(-values_.infinity, -values_.infinity);
30313057
EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity);
30323058
EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity);
30333059
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity),
@@ -3047,6 +3073,12 @@ TEST_F(DoubleTest, NaN) {
30473073
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1), "v.nan1");
30483074
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2");
30493075
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1");
3076+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, v.nan1, 1.0), "v.nan1");
3077+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, v.nan1, v.infinity), "v.nan1");
3078+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, 1.0), "v.nan1");
3079+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, v.nan1, v.infinity),
3080+
"v.nan1");
3081+
30503082
EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity), "v.infinity");
30513083
}
30523084

@@ -3069,11 +3101,28 @@ TEST_F(DoubleTest, Commutative) {
30693101

30703102
// Tests EXPECT_NEAR.
30713103
TEST_F(DoubleTest, EXPECT_NEAR) {
3104+
static const DoubleTest::TestValues& v = this->values_;
3105+
30723106
EXPECT_NEAR(-1.0, -1.1, 0.2);
30733107
EXPECT_NEAR(2.0, 3.0, 1.0);
3108+
EXPECT_NEAR(v.infinity, v.infinity, 0.0);
3109+
EXPECT_NEAR(-v.infinity, -v.infinity, 0.0);
3110+
EXPECT_NEAR(0.0, 1.0, v.infinity);
3111+
EXPECT_NEAR(v.infinity, -v.infinity, v.infinity);
3112+
EXPECT_NEAR(-v.infinity, v.infinity, v.infinity);
30743113
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25), // NOLINT
30753114
"The difference between 1.0 and 1.5 is 0.5, "
30763115
"which exceeds 0.25");
3116+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(v.infinity, -v.infinity, 0.0),
3117+
"The difference between v.infinity and -v.infinity "
3118+
"is inf, which exceeds 0.0");
3119+
EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(-v.infinity, v.infinity, 0.0),
3120+
"The difference between -v.infinity and v.infinity "
3121+
"is inf, which exceeds 0.0");
3122+
EXPECT_NONFATAL_FAILURE(
3123+
EXPECT_NEAR(v.infinity, v.close_to_infinity, v.further_from_infinity),
3124+
"The difference between v.infinity and v.close_to_infinity is inf, which "
3125+
"exceeds v.further_from_infinity");
30773126
// At this magnitude adjacent doubles are 512.0 apart, so this triggers a
30783127
// slightly different failure reporting path.
30793128
EXPECT_NONFATAL_FAILURE(

0 commit comments

Comments
 (0)