File indexing completed on 2025-01-18 09:27:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cmath>
0012 #include <cstdint>
0013 #include <limits>
0014 #include <type_traits>
0015
0016 namespace Acts {
0017
0018
0019
0020
0021
0022 template <typename T>
0023 constexpr T fastInverseSqrt(T x, int iterations = 1) noexcept {
0024 static_assert(std::numeric_limits<T>::is_iec559 &&
0025 "Only IEEE 754 is supported");
0026 static_assert(std::is_same_v<T, float> || std::is_same_v<T, double>,
0027 "Only float and double are supported");
0028 using I = std::conditional_t<std::is_same_v<T, float>, std::uint32_t,
0029 std::uint64_t>;
0030
0031 constexpr I magic =
0032 std::is_same_v<T, float> ? 0x5f3759df : 0x5fe6eb50c7b537a9;
0033
0034 union {
0035 T f;
0036 I i;
0037 } u = {x};
0038
0039 u.i = magic - (u.i >> 1);
0040
0041 for (int i = 0; i < iterations; ++i) {
0042 u.f *= 1.5f - 0.5f * x * u.f * u.f;
0043 }
0044
0045 return u.f;
0046 }
0047
0048
0049
0050
0051
0052
0053 constexpr double fastPow(double a, double b) {
0054
0055 static_assert(std::numeric_limits<double>::is_iec559);
0056
0057 constexpr std::int64_t magic = 0x3FEF127F00000000;
0058
0059 union {
0060 double f;
0061 std::int64_t i;
0062 } u = {a};
0063
0064 u.i = static_cast<std::int64_t>(b * (u.i - magic) + magic);
0065
0066 return u.f;
0067 }
0068
0069
0070
0071
0072
0073
0074 constexpr double fastPowMorePrecise(double a, double b) {
0075
0076 double r = 1.0;
0077 int exp = std::abs(static_cast<int>(b));
0078 double base = b > 0 ? a : 1 / a;
0079 while (exp != 0) {
0080 if ((exp & 1) != 0) {
0081 r *= base;
0082 }
0083 base *= base;
0084 exp >>= 1;
0085 }
0086
0087 return r * fastPow(a, b - static_cast<int>(b));
0088 }
0089
0090 }