-
Notifications
You must be signed in to change notification settings - Fork 0
/
inverse_sqrt_algo.cpp
62 lines (43 loc) · 1.42 KB
/
inverse_sqrt_algo.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# include <math.h>
# include <iostream>
# define LOG(x) std::cout << x << std::endl
void FastInverseSQRT(float f)
{
float* f_ptr = &f;
u_int32_t f_hex = * (u_int32_t * )f_ptr; // evil bit hack
u_int32_t res_hex = 0x5f3759df - (f_hex >> 1); // wtf
float res_flo = * (float*) &res_hex; // evil bit hack
float res_flo_nw = res_flo + 0.5 * (1 - res_flo *res_flo* f) * res_flo; // Newton's method
// LOG("f"); LOG(f);
// LOG("*f_ptr"); LOG(*f_ptr);
// LOG("f_ptr"); LOG(f_ptr);
// LOG("f_hex"); LOG(f_hex);
LOG("1/sqrt(f)"); LOG(1/sqrt(f));
LOG("res_flo"); LOG(res_flo);
LOG("res_flo_nw"); LOG(res_flo_nw);
}
void FastSQRT(float f)
{
// SQRT version
// Key difference in Newton's step, as we get division by y :(
// with constant 0x1fc00000 = 127 * 2**22 (assumed mu=0 in log approximation)
float* f_ptr = &f;
u_int32_t f_hex = * (u_int32_t * )f_ptr; // evil bit hack
u_int32_t res_hex = 0x1fc00000 + (f_hex >> 1); // wtf
float res_flo = * (float*) &res_hex; // evil bit hack
float res_flo_nw = res_flo - 0.5 * (res_flo - f/res_flo) ; // Newton's method
// LOG("f"); LOG(f);
// LOG("*f_ptr"); LOG(*f_ptr);
// LOG("f_ptr"); LOG(f_ptr);
// LOG("f_hex"); LOG(f_hex);
LOG("sqrt(f)"); LOG(sqrt(f));
LOG("res_flo"); LOG(res_flo);
LOG("res_flo_nw"); LOG(res_flo_nw);
}
int main(int argc, char const *argv[])
{
float f = 3765.56;
FastInverseSQRT(f);
FastSQRT(f);
return 0;
}