Created
March 6, 2022 14:41
-
-
Save a2468834/f798c9731a0d4a9dc532bcb28930da84 to your computer and use it in GitHub Desktop.
Calaulate sqrt(x) using magic number method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cmath> | |
#define SQRT_MAGIC32 0x5F375A86 | |
#define SQRT_MAGIC64 0x5FE6EB50C7B537A9 | |
using namespace std; | |
float Sqrt32(float x) { | |
uint32_t i; // The integer interpretation of x | |
float x_half = x * 0.5F; | |
float r_sqrt = x; | |
i = *(uint32_t *) &r_sqrt; | |
i = SQRT_MAGIC32 - (i >> 1); | |
r_sqrt = *(float *) &i; | |
r_sqrt = r_sqrt * (1.5F - (x_half * r_sqrt * r_sqrt)); // 1st Newton iteration | |
r_sqrt = r_sqrt * (1.5F - (x_half * r_sqrt * r_sqrt)); // 2nd Newton iteration | |
return x * r_sqrt; // x * (1/sqrt(x)) := sqrt(x) | |
} | |
double Sqrt64(double x) { | |
uint64_t i; // The integer interpretation of x | |
double x_half = x * 0.5; | |
double r_sqrt = x; | |
i = *(uint64_t *) &r_sqrt; | |
i = SQRT_MAGIC64 - (i >> 1); | |
r_sqrt = *(double *) &i; | |
r_sqrt = r_sqrt * (1.5 - (x_half * r_sqrt * r_sqrt)); // 1st Newton iteration | |
r_sqrt = r_sqrt * (1.5 - (x_half * r_sqrt * r_sqrt)); // 2nd Newton iteration | |
return x * r_sqrt; // x * (1/sqrt(x)) := sqrt(x) | |
} | |
int main(int argc, char** argv) { | |
float input32 = 17.0F; | |
cout << "[By C++ library]: " << sqrtf(input32) << endl; | |
cout << "[By fast method]: " << Sqrt32(input32) << endl; | |
double input64 = 17.0; | |
cout << "[By C++ library]: " << sqrt(input64) << endl; | |
cout << "[By fast method]: " << Sqrt64(input64) << endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Reference: https://cs.uwaterloo.ca/~m32rober/rsqrt.pdf
上述 PDF 是針對「倒數開根號」所開發的演算法

因此,只要將回傳值乘上自己,即可取得「開根號」