35 static constexpr float JPL_HALF_PI = 0.5f * std::numbers::pi_v<float>;
36 static constexpr float JPL_PI = std::numbers::pi_v<float>;
37 static constexpr float JPL_TWO_PI = 2.0f * std::numbers::pi_v<float>;
38 static constexpr float JPL_FOUR_PI = 4.0f * std::numbers::pi_v<float>;
40 static constexpr float JPL_INV_PI = std::numbers::inv_pi_v<float>;
41 static constexpr float JPL_INV_TWO_PI = std::numbers::inv_pi_v<float> * 0.5f;
42 static constexpr float JPL_INV_HALF_PI = std::numbers::inv_pi_v<float> * 2.0f;
44 template<std::
floating_po
int T>
static constexpr T JPL_TO_RAD_V = std::numbers::pi_v<T> / T(180.0);
45 template<std::
floating_po
int T>
static constexpr T JPL_TO_DEG_V = T(180.0) / std::numbers::pi_v<T>;
47 static constexpr float JPL_TO_RAD = JPL_TO_RAD_V<float>;
48 static constexpr float JPL_TO_DEG = JPL_TO_DEG_V<float>;
51 template<>
struct FloatNubmer<float> {
static constexpr float Tolerance = 1e-6f; };
52 template<>
struct FloatNubmer<double> {
static constexpr double Tolerance = 1e-8; };
54 template<std::
floating_po
int T>
57 static constexpr float JPL_FLOAT_EPS = JPL_FLOAT_EPS_V<float>;
62 template<
class T>
concept CArithmetic = std::is_arithmetic_v<T>;
63 template<
class T1,
class T2>
concept COrderedWith = std::totally_ordered_with<T1, T2>;
68 template<std::
floating_po
int T>
69 [[nodiscard]] JPL_INLINE
constexpr T
ToRadians(T degrees)
noexcept
71 return degrees * JPL_TO_RAD_V<T>;
75 template<std::
floating_po
int T>
76 [[nodiscard]] JPL_INLINE
constexpr T
ToDegrees(T radians)
noexcept
78 return radians * JPL_TO_DEG_V<T>;
82 template<std::
floating_po
int T>
83 [[nodiscard]] JPL_INLINE
constexpr bool IsNan(T x)
noexcept {
return x != x; }
86 template<CArithmetic T>
87 [[nodiscard]] JPL_INLINE
constexpr auto Abs(
const T& value)
noexcept
89 return value < 0 ? -value : value;
95 template<std::
floating_po
int T>
96 [[nodiscard]] JPL_INLINE
constexpr T
Floor(T value)
noexcept
98 if (std::is_constant_evaluated())
100 const T truncated_f =
static_cast<T
>(
static_cast<int64>(value));
101 return truncated_f -
static_cast<T
>(value < truncated_f);
105 return std::floor(value);
109 static_assert(
Floor(3.14) == 3.0);
110 static_assert(
Floor(3.0) == 3.0);
111 static_assert(
Floor(-3.14) == -4.0);
112 static_assert(
Floor(-3.0) == -3.0);
113 static_assert(
Floor(0.0) == 0.0);
114 static_assert(
Floor(-0.5) == -1.0);
118 template<std::
integral T>
119 [[nodiscard]] JPL_INLINE
constexpr T
Floor(T value)
noexcept {
return value; }
123 template<CArithmetic T>
124 [[nodiscard]] JPL_INLINE
constexpr T
Sign(T value)
noexcept
126 return (value > T(0)) ? T(1) : ((value < T(0)) ? T(-1) : T(0));
130 template<CArithmetic T>
131 [[nodiscard]] JPL_INLINE
constexpr T
Sign2(T value)
noexcept
133 if (std::is_constant_evaluated())
134 return value < T(0) ? T(-1) : T(1);
136 return std::copysign(T(1), value);
139 template<CArithmetic T1, CArithmeticAndOrderedWith<T1> T2>
142 return value > T1(0) && value < below;
145 template<std::
floating_po
int T>
146 [[nodiscard]] JPL_INLINE
constexpr bool IsNearlyZero(T value, T errorTolerance = JPL_FLOAT_EPS_V<T>)
noexcept
148 return Abs(value) <= errorTolerance;
151 template<std::
floating_po
int T>
152 [[nodiscard]] JPL_INLINE
constexpr bool IsNearlyEqual(T a, T b, T tolerance = JPL_FLOAT_EPS_V<T>)
noexcept
154 return Abs(a - b) <= tolerance;
157 template<std::
integral T>
158 [[nodiscard]] JPL_INLINE
constexpr bool IsEven(T number)
noexcept
160 return (number & T(1)) == 0;
163 template<std::
floating_po
int T>
164 [[nodiscard]] JPL_INLINE std::pair<T, T>
SinCos(T value)
noexcept
167 return { std::sin(value), std::cos(value) };
171 template<std::
floating_po
int T>
172 [[nodiscard]] JPL_INLINE
constexpr T
Lerp(
const T& v0,
const T& v1, T t)
noexcept
174 return t * (v1 - v0) + v0;
178 template<std::
integral T, std::
floating_po
int Tt>
179 [[nodiscard]] JPL_INLINE
constexpr T
Lerp(
const T& v0,
const T& v1, Tt t)
noexcept
181 return t * (v1 - v0) + v0;
185 template<std::
floating_po
int T>
186 [[nodiscard]] JPL_INLINE
constexpr T
FMA(T a, T b, T c)
noexcept
197 template <std::
floating_po
int T>
198 [[nodiscard]]
constexpr T
QNan() noexcept
200 if constexpr (!std::numeric_limits<T>::is_iec559)
201 return std::numeric_limits<T>::quiet_NaN();
202 else if constexpr (std::is_same_v<T, float>)
203 return std::bit_cast<float>(0x7fc00000u);
204 else if constexpr (std::is_same_v<T, double>)
205 return std::bit_cast<double>(0x7ff8000000000000ull);
207 return std::numeric_limits<T>::quiet_NaN();
212 template <std::
floating_po
int T>
215 if constexpr (std::is_same_v<T, float>)
217 uint32_t i = std::bit_cast<uint32_t>(x);
218 i = 0x5f3759dfu - (i >> 1);
219 return std::bit_cast<float>(i);
221 else if constexpr (std::is_same_v<T, double>)
223 uint64_t i = std::bit_cast<uint64_t>(x);
224 i = 0x5fe6eb50c7b537a9ull - (i >> 1);
225 return std::bit_cast<double>(i);
235 template <std::
floating_po
int T,
int NR>
238 const T halfx = T(0.5) * x;
239 for (
int i = 0; i < NR; ++i)
240 y = y * (T(1.5) - halfx * y * y);
245 template <std::
floating_po
int T,
int NR>
248 if (x == T(0))
return T(0);
249 if (x < T(0))
return QNan<T>();
250 if (x == std::numeric_limits<T>::infinity())
return x;
251 if (
IsNan(x))
return x;
258 if constexpr (std::is_same_v<T, float>)
259 r = T(0.5) * (r + x / r);
268 template<std::
floating_po
int T,
int NR = 2>
269 [[nodiscard]] JPL_INLINE
constexpr T
Sqrt(T x)
noexcept
271 static_assert(NR >= 0,
"NR must be >= 0");
273 if (std::is_constant_evaluated())
282 template<std::
floating_po
int T,
int NR = 2>
283 [[nodiscard]] JPL_INLINE
constexpr T
InvSqrt(T x)
noexcept
285 if (std::is_constant_evaluated())
288 return T(1.0) / std::sqrt(x);
constexpr T SqrtConstevalFallback(T x) noexcept
Pure constexpr fallback sqrt using inverse-sqrt NR.
Definition Math.h:246
constexpr T InvSqrtInitialGuess(T x) noexcept
Definition Math.h:213
constexpr T QNan() noexcept
constexpr-friendly quiet NaN (IEEE-754 only)
Definition Math.h:198
constexpr T InvSqrtNewtonRefine(T x, T y) noexcept
Scalar NR on inverse sqrt.
Definition Math.h:236
JPL_INLINE constexpr T Floor(T value) noexcept
A constexpr implementation of floor.
Definition Math.h:96
JPL_INLINE constexpr T Sign(T value) noexcept
Sign returns -1 for negative values, 1 for positive, 0 for 0.
Definition Math.h:124
JPL_INLINE constexpr T FMA(T a, T b, T c) noexcept
Inlined fuse multiply-add. Compiler in some circumstances is more eager to optimize this than std::fm...
Definition Math.h:186
JPL_INLINE constexpr T ToRadians(T degrees) noexcept
Function to convert degrees to radians.
Definition Math.h:69
JPL_INLINE constexpr bool IsNan(T x) noexcept
Definition Math.h:83
JPL_INLINE constexpr T InvSqrt(T x) noexcept
Definition Math.h:283
JPL_INLINE constexpr T Lerp(const T &v0, const T &v1, T t) noexcept
Linearly interpolate v0 towards v1.
Definition Math.h:172
JPL_INLINE constexpr T Sqrt(T x) noexcept
Definition Math.h:269
JPL_INLINE constexpr bool IsNearlyZero(T value, T errorTolerance=JPL_FLOAT_EPS_V< T >) noexcept
Definition Math.h:146
JPL_INLINE constexpr bool IsNearlyEqual(T a, T b, T tolerance=JPL_FLOAT_EPS_V< T >) noexcept
Definition Math.h:152
JPL_INLINE constexpr bool IsPositiveAndBelow(T1 value, T2 below) noexcept
Definition Math.h:140
JPL_INLINE constexpr auto Abs(const T &value) noexcept
Standard abs is not constexpr in C++20.
Definition Math.h:87
JPL_INLINE std::pair< T, T > SinCos(T value) noexcept
Definition Math.h:164
JPL_INLINE constexpr T ToDegrees(T radians) noexcept
Function to convert radians to degrees.
Definition Math.h:76
JPL_INLINE constexpr T Sign2(T value) noexcept
Sign2 returns -1 for negative values, 1 otherwise.
Definition Math.h:131
JPL_INLINE constexpr bool IsEven(T number) noexcept
Definition Math.h:158
Definition AcousticMaterial.h:36
std::int64_t int64
Definition Core.h:317