Fast inverse square root is an algorithm that estimates
i = * ( long * ) &y;
Step 2 : It takes the resulting value and does integer arithmetic on it which produces an approximation of the value we’re looking for.
i = 0x5f3759df - ( i >> 1 );
Step 3 : The result is not the approximation itself though, it is an integer which happens to be, if you reinterpret the bits as a floating point number, the approximation. So the code does the reverse of the conversion in step 1 to get back to floating point:
y = * ( float * ) &i;
Step 4 : And finally it runs a single iteration of Newton’s method to improve the approximation.
y = y * ( threehalfs - ( x2 * y * y ) ); //threehalfs = 1.5F;
The algorithm accepts a 32-bit floating-point number as the input and stores a halved value for later use. Then, treating the bits representing the floating-point number as a 32-bit integer, a logical shift right by one bit is performed and the result subtracted from the magic number 0x5F3759DF. This is the first approximation of the inverse square root of the input. Treating the bits again as a floating-point number, it runs one iteration of Newton’s approximation method, yielding a more precise approximation. Let’s say there is a number in exponent form or scientific notation:
// CPP program for fast inverse square root. #include<bits/stdc++.h> using namespace std;
// function to find the inverse square root float inverse_rsqrt( float number )
{ const float threehalfs = 1.5F;
float x2 = number * 0.5F;
float y = number;
// evil floating point bit level hacking
long i = * ( long * ) &y;
// value is pre-assumed
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
// 1st iteration
y = y * ( threehalfs - ( x2 * y * y ) );
// 2nd iteration, this can be removed
// y = y * ( threehalfs - ( x2 * y * y ) );
return y;
} // driver code int main(){
int n = 256;
float f = inverse_rsqrt(n);
cout << f << endl;
return 0;
} |
public class FastInverseSqrt {
// function to find the inverse square root
public static float inverse_rsqrt( float number) {
final float threehalfs = 1 .5F;
float x2 = number * 0 .5F;
float y = number;
// evil floating point bit level hacking
int i = Float.floatToRawIntBits(y);
i = 0x5f3759df - (i >> 1 );
y = Float.intBitsToFloat(i);
// 1st iteration
y = y * (threehalfs - (x2 * y * y));
// 2nd iteration, this can be removed
// y = y * ( threehalfs - ( x2 * y * y ) );
return y;
}
// driver code
public static void main(String[] args) {
int n = 256 ;
float f = inverse_rsqrt(n);
System.out.println(f);
}
} |
import struct
def inverse_rsqrt(number):
threehalfs = 1.5
x2 = number * 0.5
y = number
# evil floating point bit level hacking
i = struct.unpack( 'I' , struct.pack( 'f' , y))[ 0 ]
i = 0x5f3759df - (i >> 1 )
y = struct.unpack( 'f' , struct.pack( 'I' , i))[ 0 ]
# 1st iteration
y = y * (threehalfs - (x2 * y * y))
# 2nd iteration, this can be removed
# y = y * (threehalfs - (x2 * y * y))
result_bits = struct.unpack( 'I' , struct.pack( 'f' , y))[ 0 ]
size = struct.calcsize( 'I' )
if result_bits < 0 or result_bits > = ( 1 << (size * 8 )):
raise ValueError( 'result_bits out of range' )
return struct.unpack( 'f' , struct.pack( 'I' , result_bits))[ 0 ]
# driver code if __name__ = = '__main__' :
n = 256
f = inverse_rsqrt(n)
print (f)
|
using System;
class Gfg
{ // function to find the inverse square root
static float inverse_rsqrt( float number)
{
const float threehalfs = 1.5F;
float x2 = number * 0.5F;
float y = number;
// evil floating point bit level hacking
uint i = BitConverter.ToUInt32(BitConverter.GetBytes(y), 0);
// value is pre-assumed
i = 0x5f3759df - (i >> 1);
y = BitConverter.ToSingle(BitConverter.GetBytes(i), 0);
// 1st iteration
y = y * (threehalfs - (x2 * y * y));
// 2nd iteration, this can be removed
// y = y * ( threehalfs - ( x2 * y * y ) );
return y;
}
static void Main( string [] args)
{
int n = 256;
float f = inverse_rsqrt(n);
Console.WriteLine(f);
}
} |
// JavaScript program for fast inverse square root. // function to find the inverse square root function inverse_rsqrt(number)
{ const threehalfs = 1.5;
let x2 = number * 0.5;
let y = number;
// evil floating point bit level hacking
let i = new Int32Array( new Float32Array([y]).buffer)[0];
// value is pre-assumed
i = 0x5f3759df - (i >> 1);
y = new Float32Array( new Int32Array([i]).buffer)[0];
// 1st iteration
y = y * (threehalfs - (x2 * y * y));
// 2nd iteration, this can be removed
// y = y * (threehalfs - (x2 * y * y));
return y;
} // driver code let n = 256; let f = inverse_rsqrt(n); console.log(f); |
Output :
0.0623942
Time Complexity: O(1)
Space Complexity: O(1)