Skip to content

Commit 0c7515e

Browse files
Merge branch 'master' into z-function
2 parents 61cb76c + f7d656c commit 0c7515e

File tree

2 files changed

+106
-2
lines changed

2 files changed

+106
-2
lines changed

DIRECTORY.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
* [Gcd Of N Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_of_n_numbers.cpp)
175175
* [Gcd Recursive Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_recursive_euclidean.cpp)
176176
* [Integral Approximation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/integral_approximation.cpp)
177+
* [Inv Sqrt](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/inv_sqrt.cpp)
177178
* [Large Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/large_factorial.cpp)
178179
* [Large Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/large_number.h)
179180
* [Largest Power](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/largest_power.cpp)
@@ -330,5 +331,5 @@
330331
* [Brute Force String Searching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/brute_force_string_searching.cpp)
331332
* [Horspool](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/horspool.cpp)
332333
* [Knuth Morris Pratt](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/knuth_morris_pratt.cpp)
333-
* [Manacher's Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/manacher_algorithm.cpp)
334-
* [Rabin Karp](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/rabin_karp.cpp)
334+
* [Manacher Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/manacher_algorithm.cpp)
335+
* [Rabin Karp](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/rabin_karp.cpp)

math/inv_sqrt.cpp

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* @file
3+
* @brief Implementation of [the inverse square root
4+
* Root](https://medium.com/hard-mode/the-legendary-fast-inverse-square-root-e51fee3b49d9).
5+
* @details
6+
* Two implementation to calculate inverse inverse root,
7+
* from Quake III Arena (C++ version) and with a standard library (`cmath`).
8+
* This algorithm is used to calculate shadows in Quake III Arena.
9+
*/
10+
11+
#include <cassert> /// for assert
12+
#include <cmath> /// for `std::sqrt`
13+
#include <iostream> /// for IO operations
14+
#include <limits> /// for numeric_limits
15+
16+
/**
17+
* @brief This is the function that calculates the fast inverse square root.
18+
* The following code is the fast inverse square root implementation from
19+
* Quake III Arena (Adapted for C++). More information can be found at
20+
* [Wikipedia](https://en.wikipedia.org/wiki/Fast_inverse_square_root)
21+
* @tparam T floating type
22+
* @tparam iterations inverse square root, the greater the number of
23+
* iterations, the more exact the result will be (1 or 2).
24+
* @param x value to calculate
25+
* @return the inverse square root
26+
*/
27+
template <typename T = double, char iterations = 2>
28+
inline 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+
49+
/**
50+
* @brief This is the function that calculates the fast inverse square root.
51+
* The following code is the fast inverse square root with standard lib (cmath)
52+
* More information can be found at
53+
* [LinkedIn](https://www.linkedin.com/pulse/fast-inverse-square-root-still-armin-kassemi-langroodi)
54+
* @tparam T floating type
55+
* @param number value to calculate
56+
* @return the inverse square root
57+
*/
58+
template <typename T = double>
59+
T Standard_InvSqrt(T number) {
60+
T squareRoot = sqrt(number);
61+
return 1.0f / squareRoot;
62+
}
63+
64+
/**
65+
* @brief Self-test implementations
66+
* @returns void
67+
*/
68+
static 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+
83+
/**
84+
* @brief Main function
85+
* @returns 0 on exit
86+
*/
87+
int 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+
}

0 commit comments

Comments
 (0)