Skip to content

Commit e8a5010

Browse files
authored
[flang][runtime] Use std::fmod for most MOD/MODULO (#78745)
The new accurate algorithm for real MOD and MODULO in the runtime is not as fast as std::fmod(), which is also accurate. So use std::fmod() for those floating-point types that it supports. Fixes #78641.
1 parent 15e4a3c commit e8a5010

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

flang/runtime/numeric.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,21 @@ inline RT_API_ATTRS T RealMod(
144144
return std::numeric_limits<T>::quiet_NaN();
145145
} else if (std::isinf(p)) {
146146
return a;
147+
} else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double> ||
148+
std::is_same_v<T, long double>) {
149+
// std::fmod() semantics on signed operands seems to match
150+
// the requirements of MOD(). MODULO() needs adjustment.
151+
T result{std::fmod(a, p)};
152+
if constexpr (IS_MODULO) {
153+
if ((a < 0) != (p < 0)) {
154+
if (result == 0.) {
155+
result = -result;
156+
} else {
157+
result += p;
158+
}
159+
}
160+
}
161+
return result;
147162
} else {
148163
// The standard defines MOD(a,p)=a-AINT(a/p)*p and
149164
// MODULO(a,p)=a-FLOOR(a/p)*p, but those definitions lose

0 commit comments

Comments
 (0)