Skip to content

Instantly share code, notes, and snippets.

@a2468834
Created March 6, 2022 14:41
Show Gist options
  • Save a2468834/f798c9731a0d4a9dc532bcb28930da84 to your computer and use it in GitHub Desktop.
Save a2468834/f798c9731a0d4a9dc532bcb28930da84 to your computer and use it in GitHub Desktop.
Calaulate sqrt(x) using magic number method
#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;
}
@a2468834
Copy link
Author

a2468834 commented Mar 6, 2022

Reference: https://cs.uwaterloo.ca/~m32rober/rsqrt.pdf

上述 PDF 是針對「倒數開根號」所開發的演算法
因此,只要將回傳值乘上自己,即可取得「開根號」

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment