Skip to content

Instantly share code, notes, and snippets.

@JayBazuzi
Last active April 11, 2020 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JayBazuzi/b4ae6f6acd8ef368f6da2c5ae529752e to your computer and use it in GitHub Desktop.
Save JayBazuzi/b4ae6f6acd8ef368f6da2c5ae529752e to your computer and use it in GitHub Desktop.
float Q_rsqrt_original(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;
}
inline float InverseSquare_intial_fast_guess(float number)
{
long i = *(long*)&number; // evil floating point bit level hacking
i = 0x5f3759df - (i >> 1); // what the fuck?
return *(float*)&i;
}
inline float InverseSquare_improve_estimate_with_newtons_method(float number, float estimate)
{
const float x2 = number * 0.5F;
return estimate * (1.5F - (x2 * estimate * estimate));
}
float Q_get_inverse_square_root(float number)
{
float estimate = InverseSquare_intial_fast_guess(number);
estimate = InverseSquare_improve_estimate_with_newtons_method(number, estimate); // 1st iteration
// estimate = improve_estimate_with_newtons_method(number, estimate); // 2nd iteration, this can be removed
return estimate;
}
#include "pch.h"
#include "CppUnitTest.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
// https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code
inline float InverseSquare_intial_fast_guess(float number)
{
long i = *(long*)&number; // evil floating point bit level hacking
i = 0x5f3759df - (i >> 1); // what the fuck?
return *(float*)&i;
}
inline float InverseSquare_improve_estimate_with_newtons_method(float number, float estimate)
{
const float x2 = number * 0.5F;
return estimate * (1.5F - (x2 * estimate * estimate));
}
float Q_get_inverse_square_root(float number)
{
float estimate = InverseSquare_intial_fast_guess(number);
estimate = InverseSquare_improve_estimate_with_newtons_method(number, estimate); // 1st iteration
// estimate = improve_estimate_with_newtons_method(number, estimate); // 2nd iteration, this can be removed
return estimate;
}
float Q_rsqrt_original(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;
}
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
for (float i = 0; i < 10000; i += 3.14f)
{
Assert::AreEqual(Q_rsqrt_original(i), Q_get_inverse_square_root(i));
}
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment