diff --git a/AK/Math.h b/AK/Math.h index 925ebd2b6b1..8bb6c5a254a 100644 --- a/AK/Math.h +++ b/AK/Math.h @@ -391,12 +391,37 @@ constexpr T fmod(T x, T y) : "u"(y)); } while (fpu_status & 0x400); return x; + // FIXME: Add a generic implementation of this + // Neither + // ``` + // return x - (y * trunc(x/y)) + // ``` + // nor + // ``` + // double result = remainder(std::fabs(x), y = std::fabs(y)); + // if (std::signbit(result)) + // result += y; + // return std::copysign(result, x); + // ``` from (https://en.cppreference.com/w/cpp/numeric/math/fmod) + // provide enough precision for all cases + // other implementations seem to do this by hand with some fixed point steps in between + // For `remainder` the trivial solution of + // ``` + // return x - (y * rint(x/y)) + // ``` + // might work + #else # if defined(AK_OS_SERENITY) // TODO: Add implementation for this function. TODO(); # endif - return __builtin_fmod(x, y); + if constexpr (IsSame) + return __builtin_fmodl(x, y); + if constexpr (IsSame) + return __builtin_fmod(x, y); + if constexpr (IsSame) + return __builtin_fmodf(x, y); #endif } @@ -420,7 +445,12 @@ constexpr T remainder(T x, T y) // TODO: Add implementation for this function. TODO(); # endif - return __builtin_fmod(x, y); + if constexpr (IsSame) + return __builtin_remainderl(x, y); + if constexpr (IsSame) + return __builtin_remainder(x, y); + if constexpr (IsSame) + return __builtin_remainderf(x, y); #endif } }