fast inverse square
C programming
C++ programming
optimization techniques
numerical methods

Fast inverse square of double in C/C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The famous “fast inverse square root” trick became popular because it produced a fast approximation of 1 / sqrt(x) for float. The same idea can be adapted to double, but the result is mostly of historical or educational interest now because modern compilers and hardware often make 1.0 / sqrt(x) or platform intrinsics a better engineering choice.

So the right question is not only “can I do it for double?” but also “should I still do it?”

The Core Idea

The original trick works by:

  1. reinterpreting the floating-point bits as an integer
  2. applying a “magic constant” to get a rough approximation
  3. improving the result with Newton-Raphson iteration

For double, you need a 64-bit integer representation and a different constant.

A Double-Precision Version

Here is a common demonstration form in C++.

cpp
1#include <bit>
2#include <cstdint>
3#include <iostream>
4
5
6double fast_inv_sqrt(double x) {
7    std::uint64_t i = std::bit_cast<std::uint64_t>(x);
8    i = 0x5fe6eb50c7b537a9ULL - (i >> 1);
9    double y = std::bit_cast<double>(i);
10
11    y = y * (1.5 - 0.5 * x * y * y);
12    return y;
13}
14
15int main() {
16    double x = 9.0;
17    std::cout << fast_inv_sqrt(x) << "\n";
18    std::cout << 1.0 / std::sqrt(x) << "\n";
19}

This gives an approximation. You can add another Newton step for better accuracy.

Accuracy Versus Speed Tradeoff

The bit trick provides a rough starting point. Newton iteration sharpens it:

cpp
y = y * (1.5 - 0.5 * x * y * y);
y = y * (1.5 - 0.5 * x * y * y);

More iterations improve accuracy but reduce the speed advantage. On modern CPUs, that tradeoff is often not worth it unless you are working in a very specialized environment.

Be Careful About Undefined Behavior in Older C/C++ Code

Old examples often use pointer punning or unions in ways that are easy to get wrong or rely on compiler-specific behavior. In modern C++, std::bit_cast is the cleanest way to express the reinterpretation.

If you write C instead of C++, prefer a safe byte-copy approach rather than violating aliasing rules casually.

When the Trick Still Makes Sense

This technique can still be useful for:

  • education about floating-point representation
  • historical graphics code study
  • approximate math in constrained environments
  • experiments where exact IEEE accuracy is not required

For most production numeric code, measure before assuming it helps. That advice matters even more for double, where callers often care about precision enough that the approximation may not justify itself.

If exactness, portability, and maintainability matter more than a micro-optimization experiment, the standard library call is usually the better default.

Common Pitfalls

  • Assuming the famous float magic constant also works for double.
  • Copying old pointer-cast code that violates strict aliasing rules.
  • Using the approximation in code that actually requires strong numerical accuracy.
  • Benchmarking without compiler optimizations and drawing the wrong conclusion about speed.
  • Forgetting that modern sqrt implementations and hardware instructions may already be excellent.

Summary

  • The fast inverse square root trick can be adapted to double, but it is mostly a specialized optimization today.
  • A double version needs a 64-bit bit reinterpretation and a different magic constant.
  • Newton-Raphson refinement improves the approximation at the cost of speed.
  • Modern code should use safe bit reinterpretation methods such as std::bit_cast.
  • Measure against 1.0 / std::sqrt(x) before choosing the approximation in real software.

Course illustration
Course illustration

All Rights Reserved.