<p>应优先使用 std::acos(-1.0) 或 std::atan(1.0) * 4.0 获取 double 精度 π,二者精度达约 17 位;C++20 起可声明为 constexpr 编译期常量;高精度需求应直接采用 boost::multiprecision 等成熟库而非手写算法。</p>

用 std::atan 或 std::acos 直接获取 double 精度 π
绝大多数 C++ 场景根本不需要自己算 π —— 标准库已经提供了足够精确的值。直接调用 std::atan(1.0) * 4.0 或 std::acos(-1.0) 就能得到 double 类型下最接近真实 π 的值(约 17 位有效数字)。
常见错误是手写 3.14159265358979323846 字面量,这不仅易错,还可能因编译器截断或浮点字面量解析差异引入微小偏差。
-
std::acos(-1.0)更简洁,但需确保<cmath>已包含,且传入值在 [-1, 1] 范围内(否则返回NaN) -
std::atan(1.0) * 4.0数学意义更直观,但多一次乘法,无实质影响 - 不要用
float版本(如std::atanf),精度掉到 7 位,对多数计算已不够用
需要更高精度时,别手写算法——用 boost::multiprecision
如果真要算到几百位、几千位(比如验证算法或教学演示),自己实现 Chudnovsky 或 Machin 公式极易出错:阶乘溢出、中间项精度丢失、收敛判断不稳、除法舍入累积……这些坑比代码本身还耗时间。
直接用 boost::multiprecision::cpp_dec_float_100 这类现成类型,配合已验证的数值库函数,才是合理路径。
立即学习“C++免费学习笔记(深入)”;
- 示例:用
boost::multiprecision::cpp_dec_float_50算 50 位 π,只需调boost::math::constants::pi<T>(),一行搞定 - 手动实现 Leibniz 级数(
4*(1 - 1/3 + 1/5 - 1/7 + ...))看似简单,但收敛极慢——算 10⁶ 项才勉强到 6 位准确小数,且double累加会因舍入误差反向漂移 - Chudnovsky 公式虽快,但涉及大整数阶乘和高精度除法,C++ 原生类型完全无法支撑,必须依赖外部大数库
编译期常量 π:用 constexpr + 标准库函数(C++20 起)
C++20 允许 std::acos 和 std::atan 在 constexpr 上下文中使用,意味着你可以把 π 定义为编译期常量,避免运行时调用开销。
注意:不是所有编译器默认启用此特性,Clang 需 -std=c++20,GCC 10+ 支持,MSVC 2019 v16.10+ 支持;且必须用 constexpr 变量声明,不能只靠宏或字面量模拟。
- 正确写法:
constexpr double pi = std::acos(-1.0); - 错误写法:
#define PI 3.14159265358979323846—— 宏不参与类型检查,也无法用于constexpr场景(如数组维度) - 若需 float 版本,应显式写
constexpr float pi_f = static_cast<float>(std::acos(-1.0));,避免隐式截断不可控
自定义高精度实现前,先确认是否真需要“算”π
很多所谓“高精度 π 计算需求”,实际只是想用高精度 π 值做后续运算。这时候真正该做的,是选对数值类型和常量来源,而不是重写算法。
比如用 long double 时,不同平台精度差异极大(x86 是 80-bit 扩展精度,ARM64 通常是 IEEE-754 binary64),直接用 std::acos(-1.0L) 比自己“算”更可靠。
- Linux x86_64 下
long double可能有 19 位有效数字,但 macOS / iOS 已将其降级为普通double,此时再用std::acos(-1.0L)不会提升精度 - 如果项目已用
boost::multiprecision,就别重复造轮子;如果没引入任何大数库,又确实需要百位以上 π,那优先考虑 Python 或专用工具生成常量表,而非在 C++ 里实时计算 - 真正需要动态计算 π 的场景极少:比如硬件受限嵌入式系统(无标准库)、特定密码学协议要求、或算法课设——这种情况下,务必用已知收敛性与误差界的公式,并做中间项截断误差估计
最常被忽略的一点:π 的“精度”永远受限于你使用的数值类型和计算路径。从源码里抄一段 Chudnovsky 实现,不解决大整数、高精度除法、舍入控制,结果很可能还不如 std::acos(-1.0) 可靠。










