Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
inv_sqrt.cpp File Reference

Implementation of the inverse square root Root. More...

#include <cassert>
#include <cmath>
#include <iostream>
#include <limits>
Include dependency graph for inv_sqrt.cpp:

Functions

template<typename T = double, char iterations = 2>
Fast_InvSqrt (T x)
 for numeric_limits
 
template<typename T = double>
Standard_InvSqrt (T number)
 This is the function that calculates the fast inverse square root. The following code is the fast inverse square root with standard lib (cmath) More information can be found at LinkedIn
 
static void test ()
 Self-test implementations.
 
int main ()
 Main function.
 

Detailed Description

Implementation of the inverse square root Root.

Two implementation to calculate inverse inverse root, from Quake III Arena (C++ version) and with a standard library (cmath). This algorithm is used to calculate shadows in Quake III Arena.

Function Documentation

◆ Fast_InvSqrt()

template<typename T = double, char iterations = 2>
T Fast_InvSqrt ( T x)
inline

for numeric_limits

for assert for std::sqrt for IO operations

This is the function that calculates the fast inverse square root. The following code is the fast inverse square root implementation from Quake III Arena (Adapted for C++). More information can be found at Wikipedia

Template Parameters
Tfloating type
iterationsinverse square root, the greater the number of iterations, the more exact the result will be (1 or 2).
Parameters
xvalue to calculate
Returns
the inverse square root
28 {
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}

◆ main()

int main ( void )

Main function.

Returns
0 on exit
87 {
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 endl(T... args)
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 numeric_limits
Definition inv_sqrt.cpp:28
Here is the call graph for this function:

◆ Standard_InvSqrt()

template<typename T = double>
T Standard_InvSqrt ( T number)

This is the function that calculates the fast inverse square root. The following code is the fast inverse square root with standard lib (cmath) More information can be found at LinkedIn

Template Parameters
Tfloating type
Parameters
numbervalue to calculate
Returns
the inverse square root
59 {
60 T squareRoot = sqrt(number);
61 return 1.0f / squareRoot;
62}
T sqrt(T... args)

◆ test()

static void test ( )
static

Self-test implementations.

Returns
void
68 {
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}
T fabs(T... args)
Here is the call graph for this function: