TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
inv_sqrt.cpp
Go to the documentation of this file.
1
11#include <cassert>
12#include <cmath>
13#include <cstdint>
14#include <iostream>
15#include <limits>
27template <typename T = double, char iterations = 2>
28inline T Fast_InvSqrt(T x) {
29 using Tint = typename std::conditional<sizeof(T) == 8, std::int64_t,
30 std::int32_t>::type;
31 T y = x;
32 T x2 = y * 0.5;
33
34 Tint i =
35 *reinterpret_cast<Tint *>(&y); // Store floating-point bits in integer
36
37 i = (sizeof(T) == 8 ? 0x5fe6eb50c7b537a9 : 0x5f3759df) -
38 (i >> 1); // Initial guess for Newton's method
39
40 y = *reinterpret_cast<T *>(&i); // Convert new bits into float
41
42 y = y * (1.5 - (x2 * y * y)); // 1st iteration Newton's method
43 if (iterations == 2) {
44 y = y * (1.5 - (x2 * y * y)); // 2nd iteration, the more exact result
45 }
46 return y;
47}
48
58template <typename T = double>
59T Standard_InvSqrt(T number) {
60 T squareRoot = sqrt(number);
61 return 1.0f / squareRoot;
62}
63
68static void test() {
69 const float epsilon = 1e-3f;
70
71 /* Tests with multiple values */
72 assert(std::fabs(Standard_InvSqrt<float>(100.0f) - 0.0998449f) < epsilon);
73 assert(std::fabs(Standard_InvSqrt<double>(36.0f) - 0.166667f) < epsilon);
74 assert(std::fabs(Standard_InvSqrt(12.0f) - 0.288423f) < epsilon);
75 assert(std::fabs(Standard_InvSqrt<double>(5.0f) - 0.447141f) < epsilon);
76
77 assert(std::fabs(Fast_InvSqrt<float, 1>(100.0f) - 0.0998449f) < epsilon);
78 assert(std::fabs(Fast_InvSqrt<double, 1>(36.0f) - 0.166667f) < epsilon);
79 assert(std::fabs(Fast_InvSqrt(12.0f) - 0.288423) < epsilon);
80 assert(std::fabs(Fast_InvSqrt<double>(5.0f) - 0.447141) < epsilon);
81}
82
87int main() {
88 test(); // run self-test implementations
89 std::cout << "The Fast inverse square root of 36 is: "
90 << Fast_InvSqrt<float, 1>(36.0f) << std::endl;
91 std::cout << "The Fast inverse square root of 36 is: "
92 << Fast_InvSqrt<double, 2>(36.0f) << " (2 iterations)"
93 << std::endl;
94 std::cout << "The Fast inverse square root of 100 is: "
95 << Fast_InvSqrt(100.0f)
96 << " (With default template type and iterations: double, 2)"
97 << std::endl;
98 std::cout << "The Standard inverse square root of 36 is: "
99 << Standard_InvSqrt<float>(36.0f) << std::endl;
100 std::cout << "The Standard inverse square root of 100 is: "
101 << Standard_InvSqrt(100.0f)
102 << " (With default template type: double)" << std::endl;
103}
T Standard_InvSqrt(T number)
This is the function that calculates the fast inverse square root. The following code is the fast inv...
Definition inv_sqrt.cpp:59
static void test()
Self-test implementations.
Definition inv_sqrt.cpp:68
T Fast_InvSqrt(T x)
for std::sqrt
Definition inv_sqrt.cpp:28
int main()
Main function.
Definition inv_sqrt.cpp:87