diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp index 25e58e79dbba0e..38835c2b753cef 100644 --- a/flang/runtime/numeric.cpp +++ b/flang/runtime/numeric.cpp @@ -261,12 +261,10 @@ template inline RT_API_ATTRS T Spacing(T x) { // NEAREST (16.9.139) template inline RT_API_ATTRS T Nearest(T x, bool positive) { - auto spacing{Spacing(x)}; - if (x == 0) { - auto least{std::numeric_limits::denorm_min()}; - return positive ? least : -least; + if (positive) { + return std::nextafter(x, std::numeric_limits::infinity()); } else { - return positive ? x + spacing : x - spacing; + return std::nextafter(x, -std::numeric_limits::infinity()); } } diff --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp index 5afed750c0b183..43263d1ac42315 100644 --- a/flang/unittests/Runtime/Numeric.cpp +++ b/flang/unittests/Runtime/Numeric.cpp @@ -86,7 +86,7 @@ TEST(Numeric, Nearest) { EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true), Real<8>{1.0} + std::ldexp(Real<8>{1.0}, -52)); EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, false), - Real<8>{1.0} - std::ldexp(Real<8>{1.0}, -52)); + Real<8>{1.0} - 0.5 * std::ldexp(Real<8>{1.0}, -52)); } TEST(Numeric, Nint) {