TheAlgorithms/C++ 1.0.0
All the 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 <cstdint>
#include <iostream>
#include <limits>
Include dependency graph for inv_sqrt.cpp:

Go to the source code of this file.

Functions

template<typename T = double, char iterations = 2>
Fast_InvSqrt (T x)
 for std::sqrt
 
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.

Definition in file inv_sqrt.cpp.

Function Documentation

◆ Fast_InvSqrt()

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

for std::sqrt

for assert for IO operations for numeric_limits

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

Definition at line 28 of file inv_sqrt.cpp.

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

Definition at line 87 of file inv_sqrt.cpp.

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 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

◆ 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

Definition at line 59 of file inv_sqrt.cpp.

59 {
60 T squareRoot = sqrt(number);
61 return 1.0f / squareRoot;
62}

◆ test()

static void test ( )
static

Self-test implementations.

Returns
void

Definition at line 68 of file inv_sqrt.cpp.

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}