invLength = fastInvSqrt(x*x + y*y)
x *= invLength
y *= invLength
This is much faster on old CPUs.
#include <stdint.h>
inline float fastInvSqrt(float number) {
union {
float f;
uint32_t i;
} conv;
conv.f = number;
const float x2 = number * 0.5f;
const float threehalfs = 1.5f;
conv.i = 0x5f3759df - (conv.i >> 1);
conv.f = conv.f * (
threehalfs - (x2 * conv.f * conv.f)
);
return conv.f;
}
| Step | Description |
|---|---|
| Bit-level hack | Approximates inverse square root using floating-point bits |
| Magic number | 0x5f3759df gives an initial approximation |
| Newton-Raphson | Improves approximation accuracy |
float vx = 10.0f;
float vy = 5.0f;
float invLength = fastInvSqrt(vx*vx + vy*vy);
vx *= invLength;
vy *= invLength;
float dx = x2 - x1;
float dy = y2 - y1;
float distSq = dx*dx + dy*dy;
float distance = distSq * fastInvSqrt(distSq);
| Benefit | Why It Matters |
|---|---|
| Very fast | Much faster than sqrt + division on old hardware |
| Low CPU usage | Good for consoles with low clock speeds |
| Great for hot loops | Useful in rendering, physics and particles |
| Classic game optimization | Used in famous game engines |
| Problem | Description |
|---|---|
| Approximation | Not perfectly accurate |
| Hard to understand | Bit-level tricks are confusing |
| Modern CPUs improved | Modern hardware sqrt is much faster today |
Old hardware rewards:
Fast inverse square root became legendary because it represents the mindset of old-school engine optimization.