Skip to content

Commit 39c2f59

Browse files
authored
[flang][runtime] Fix NEAREST() when exponent decreases (#75368)
When the result of NEAREST() has an exponent less than that of the argument (e.g., NEAREST(1.,-1.) and NEAREST(-1.,1.)), the result was wrong, because the increment value uses the result of SPACING() in terms of the argument. Fix by just calling into the C runtime routine std::nextafter().
1 parent 933882f commit 39c2f59

File tree

2 files changed

+4
-6
lines changed

2 files changed

+4
-6
lines changed

flang/runtime/numeric.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,10 @@ template <int PREC, typename T> inline RT_API_ATTRS T Spacing(T x) {
261261
// NEAREST (16.9.139)
262262
template <int PREC, typename T>
263263
inline RT_API_ATTRS T Nearest(T x, bool positive) {
264-
auto spacing{Spacing<PREC>(x)};
265-
if (x == 0) {
266-
auto least{std::numeric_limits<T>::denorm_min()};
267-
return positive ? least : -least;
264+
if (positive) {
265+
return std::nextafter(x, std::numeric_limits<T>::infinity());
268266
} else {
269-
return positive ? x + spacing : x - spacing;
267+
return std::nextafter(x, -std::numeric_limits<T>::infinity());
270268
}
271269
}
272270

flang/unittests/Runtime/Numeric.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ TEST(Numeric, Nearest) {
8686
EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true),
8787
Real<8>{1.0} + std::ldexp(Real<8>{1.0}, -52));
8888
EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, false),
89-
Real<8>{1.0} - std::ldexp(Real<8>{1.0}, -52));
89+
Real<8>{1.0} - 0.5 * std::ldexp(Real<8>{1.0}, -52));
9090
}
9191

9292
TEST(Numeric, Nint) {

0 commit comments

Comments
 (0)