Fast Inversed Squareroot Function – Quake 3

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.

				
					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

💡 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 x is calculated by: x=(1+M223)2E127()

And, bit representation of x would be: M+223E()

For x small x[0,1), we could approximate x by: xlog2(1+x), then we can claim that:

log2(1+x)=x+μ;(μ is empirically chosen at 0.043)

Looking at an arbitrary value x, applying (*), we have:

log2x=log2((1+M223)2E127)=log2(1+M223)+E127

Since M223[0,1), we now apply the approximation rule:

log2(1+M223)=M223+μ

Then:

log2x=M223+μ+E127=M223+223E223+μ127=1223(M+223Ebit representation (**))+μ127

The meaning of the line of code: -(i >>1)

log2(1x)=log2(x12)=12log2(x)

Let Γ=1xlog2(Γ)=log2(1x)=12log2(x)

We replace the logarithm with the bit representation for both sides:

1223(MΓ+223EΓ)+μ127=12(1223(Mx+223Ex)+μ127)MΓ+223EΓ=32223(127μ)0x5f3759df12(Mx+223Ex)xi>>1

Here reveals the secret of this line of code:

 
				
					i  = 0x5f3759df - ( i >> 1 );  // what the fuck?
				
			

xnew=xoldf(x)f(x)

Let f(y)=1y2x, then: f(y)=0y=1x. We try to solve f(y)=0 using Newton Method. First we compute the derivative of f(y):

f(y)=yxy32

Then

ynew=yf(y)f(y)=yyxy32=y(32x2y2)

This is the meaning of the last line of code:

				
					 y  = y * ( threehalfs - ( x2 * y * y ) );
				
			

Subscribe to SkyGLab

Scroll to Top