Improve NaN handling in absl::Duration arithmetic. PiperOrigin-RevId: 774936932 Change-Id: Ibde499b8c9825b4357edf71cfcb9c45eb75f4702
diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 38c4b63..fb7c90a 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc
@@ -469,7 +469,7 @@ Duration& Duration::operator*=(double r) { if (time_internal::IsInfiniteDuration(*this) || !IsFinite(r)) { - const bool is_neg = std::signbit(r) != (rep_hi_.Get() < 0); + const bool is_neg = std::isnan(r) || std::signbit(r) != (rep_hi_.Get() < 0); return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); } return *this = ScaleDouble<std::multiplies>(*this, r); @@ -485,7 +485,7 @@ Duration& Duration::operator/=(double r) { if (time_internal::IsInfiniteDuration(*this) || !IsValidDivisor(r)) { - const bool is_neg = std::signbit(r) != (rep_hi_.Get() < 0); + const bool is_neg = std::isnan(r) || std::signbit(r) != (rep_hi_.Get() < 0); return *this = is_neg ? -InfiniteDuration() : InfiniteDuration(); } return *this = ScaleDouble<std::divides>(*this, r);
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 1e3fe67..164ad6b 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc
@@ -841,18 +841,18 @@ TEST(Duration, NaN) { // Note that IEEE 754 does not define the behavior of a nan's sign when it is - // copied, so the code below allows for either + or - InfiniteDuration. + // copied. We return -InfiniteDuration in either case. #define TEST_NAN_HANDLING(NAME, NAN) \ do { \ const auto inf = absl::InfiniteDuration(); \ auto x = NAME(NAN); \ - EXPECT_TRUE(x == inf || x == -inf); \ + EXPECT_TRUE(x == -inf); \ auto y = NAME(42); \ y *= NAN; \ - EXPECT_TRUE(y == inf || y == -inf); \ + EXPECT_TRUE(y == -inf); \ auto z = NAME(42); \ z /= NAN; \ - EXPECT_TRUE(z == inf || z == -inf); \ + EXPECT_TRUE(z == -inf); \ } while (0) const double nan = std::numeric_limits<double>::quiet_NaN();