The pi constant is usually available in the math.h header

#define _USE_MATH_DEFINES // Needed on MSVC
#include <cmath>
#define M_PI       3.14159265358979323846   // pi

Anyway besides being defined as the ratio between the circumference and diameter, the value of \( \pi \) can also be approximate with the help of Leibniz’s formula

\[\sum_{n=0}^\infty \, \frac{(-1)^n}{2n+1} \;=\; \frac{\pi}{4}\]

and this can be computed in \( O(n) \) where \( n \) is the number of iterations at runtime or directly at compile-time moving the bulk of the work to the compiler itself with templates

#include<iostream>

template <unsigned long long Iteration>
struct pi_calculator {
  static constexpr double value() {
    return (4.0 * ((Iteration % 2 == 0) ? 1.0 : -1.0) / (2.0 * Iteration + 1.0))
      + pi_calculator<Iteration - 1>::value();
  }
};

template <>
struct pi_calculator<0> {
  static constexpr double value() {
    return 4.0;
  }
};

template <unsigned long long Iterations>
struct compileTimePi {
  static constexpr double value() {
    return pi_calculator<Iterations>::value();
  }
};

double runtimeComputePi(const unsigned long long iterations) {
  double pi = 0;
  for (unsigned long long i = iterations; i > 0; --i) {
    pi += ((i % 2 == 0) ? 1.0 : -1.0) * 4.0 / (2.0*i + 1.0);
  }
  pi += 4.0;
  return pi;
}

int main() {
  const unsigned long long iterations = 1000u; // cfr. -ftemplate-depth

  double rtPi = runtimeComputePi(iterations);
  double ctPi = compileTimePi<iterations>::value();

  std::cout.precision(10);
  std::cout << "Runtime pi: \t\t" << rtPi << std::endl;
  std::cout << "Compile-time pi: \t" << ctPi << std::endl;

  return 0;
}