This technique gained popularity in the early days of computer graphics when processing power was limited. It’s an approximation method used to calculate the reciprocal of a square root (1 / sqrt(x)) faster than the standard division and square root functions. This was implemented in Quake 3 game.
The source code
float Q_rsqrt(float number)
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
Let’s dig into the source code
The IEEE 754 Standard
💡 Wikipedia Single-precision floating-point format
According to this standard, a float number is represented as 3 parts of 32 bits: Sign bit (x1), Exponential bits (x8), Mantissa bits (x23).
Then, a positive float number is calculated by:
And, bit representation of would be:
Extract binary information from the
For small , we could approximate by: , then we can claim that:
Looking at an arbitrary value , applying (*), we have:
Since , we now apply the approximation rule:
Then:
Calculate using
The meaning of the line of code: -(i >>1)
Let
We replace the logarithm with the bit representation for both sides:
Here reveals the secret of this line of code:
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
Newton Iteration Method for Finding Approximation of Root
Let , then: . We try to solve using Newton Method. First we compute the derivative of :
Then
This is the meaning of the last line of code:
y = y * ( threehalfs - ( x2 * y * y ) );