From ae963e444fcdf1ad45f662e0c706568f34506528 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 11 May 2022 07:21:09 -0700 Subject: [PATCH] Implement constexpr isfinite to avoid producing NaN --- include/fmt/format.h | 10 +++++++--- test/format-test.cc | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 9951d1bb..80074f12 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2343,12 +2343,16 @@ struct has_isfinite> template ::value&& has_isfinite::value)> FMT_CONSTEXPR20 bool isfinite(T value) { - if (is_constant_evaluated()) return !isnan(value - value); + constexpr T inf = T(std::numeric_limits::infinity()); + if (is_constant_evaluated()) + return !isnan(value) && value != inf && value != -inf; return std::isfinite(value); } template ::value)> -constexpr bool isfinite(T value) { - return value - value == 0; // std::isfinite doesn't support __float128. +FMT_CONSTEXPR bool isfinite(T value) { + T inf = T(std::numeric_limits::infinity()); + // std::isfinite doesn't support __float128. + return !isnan(value) && value != inf && value != -inf; } template ::value)> diff --git a/test/format-test.cc b/test/format-test.cc index 0743b60c..b4e1e194 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -89,6 +89,8 @@ template void check_isfinite() { EXPECT_TRUE(isfinite(Float(fmt::detail::max_value()))); // Use double because std::numeric_limits is broken for __float128. using limits = std::numeric_limits; + FMT_CONSTEXPR20 auto result = isfinite(Float(limits::infinity())); + EXPECT_FALSE(result); EXPECT_FALSE(isfinite(Float(limits::infinity()))); EXPECT_FALSE(isfinite(Float(-limits::infinity()))); EXPECT_FALSE(isfinite(Float(limits::quiet_NaN())));