From 30e369cf24c0ea99e209b75fba5d65d55ef94aec Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 2 Sep 2023 13:59:06 +0200 Subject: src: fix the move speed formula a abit --- compat/math.hpp | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 compat/math.hpp (limited to 'compat') diff --git a/compat/math.hpp b/compat/math.hpp new file mode 100644 index 00000000..d5b628c4 --- /dev/null +++ b/compat/math.hpp @@ -0,0 +1,79 @@ +#pragma once + +#include +#include + +namespace floormat::math::detail { + +constexpr double sqrt_newton_raphson(double x, double curr, double prev) +{ + return curr == prev + ? curr + : sqrt_newton_raphson(x, 0.5 * (curr + x / curr), curr); +} + +template requires std::is_floating_point_v struct float_constants; + +template<> +struct float_constants +{ + static constexpr auto quiet_nan = std::bit_cast(uint64_t(0x7FF8000000000000ULL)); + static constexpr auto positive_infinity = std::bit_cast(uint64_t(0x7FF0000000000000ULL)); + static constexpr auto negative_infinity = std::bit_cast(uint64_t(0xFFF0000000000000ULL)); +}; + +template<> +struct float_constants +{ + static constexpr auto quiet_nan = std::bit_cast(uint32_t(0x7FC00000U)); + static constexpr auto positive_infinity = std::bit_cast(uint32_t(0x7F800000U)); + static constexpr auto negative_infinity = std::bit_cast(uint32_t(0xFF800000U)); +}; + +} // namespace floormat::math::detail + +namespace floormat::math { + +template +constexpr inline T sqrt(T x) +requires std::is_floating_point_v +{ + if (std::is_constant_evaluated()) + { + using K = detail::float_constants; + return x >= 0 && x < K::positive_infinity + ? T(detail::sqrt_newton_raphson(double(x), double(x), 0)) + : K::quiet_nan; + } + else + return std::sqrt(x); +} + +template +requires std::is_integral_v +constexpr inline double sqrt(T x) +{ + return sqrt(double(x)); +} + +template +requires std::is_floating_point_v +constexpr inline T ceil(T x) +{ + if (std::is_constant_evaluated()) + { +#ifdef __GNUG__ + return __builtin_ceil(x); +#else + const auto x0 = uint64_t(x); + if (x > x0) + return T(x0 + uint64_t(1)); + else + return x0; +#endif + } + else + return std::ceil(x); +} + +} // namespace floormat::math -- cgit v1.2.3