diff --git a/AK/Math.h b/AK/Math.h index fe03085e76..982ae5c89a 100644 --- a/AK/Math.h +++ b/AK/Math.h @@ -757,6 +757,36 @@ constexpr T ceil(T num) #endif } +template +constexpr T floor(T num) +{ + if (is_constant_evaluated()) { + if (num < NumericLimits::min() || num > NumericLimits::max()) + return num; + return (static_cast(static_cast(num)) == num) + ? static_cast(num) + : static_cast(num) - ((num > 0) ? 0 : 1); + } +#if ARCH(AARCH64) + AARCH64_INSTRUCTION(frintm, num); +#else + return __builtin_floor(num); +#endif +} + +template +constexpr T round(T x) +{ + CONSTEXPR_STATE(round, x); + // Note: This is break-tie-away-from-zero, so not the hw's understanding of + // "nearest", which would be towards even. + if (x == 0.) + return x; + if (x > 0.) + return floor(x + .5); + return ceil(x - .5); +} + #undef CONSTEXPR_STATE #undef AARCH64_INSTRUCTION }