C++ 标准库 <numbers>

std::numbers 是 C++20 中引入的一个标准库模块,主要用于提供一组常用的数学常量。

std::numbers位于 <numbers> 头文件中,并且包含了很多数学常量,涵盖了圆周率、自然对数的底数、黄金比例等常见常数。

C++ 使用这些常量可以提高代码的可读性、精度和效率,避免了重复定义和手动输入常数值。

std::numbers 模块包含的常量

std::numbers 命名空间下包含以下成员:

template<floating_point T> inline constexpr T e_v<T> // 自然常数e
template<floating_point T> inline constexpr T log2e_v<T> // log2e
template<floating_point T> inline constexpr T log10e_v<T> // log10e
template<floating_point T> inline constexpr T pi_v<T> // 圆周率π
template<floating_point T> inline constexpr T inv_pi_v<T> // 1/π
template<floating_point T> inline constexpr T inv_sqrtpi_v<T> //1/根号π
template<floating_point T> inline constexpr T ln2_v<T> // ln2
template<floating_point T> inline constexpr T ln10_v<T> // ln10
template<floating_point T> inline constexpr T sqrt2_v<T> //根号2
template<floating_point T> inline constexpr T sqrt3_v<T> //根号3
template<floating_point T> inline constexpr T inv_sqrt3_v<T> // 1/根号3
template<floating_point T> inline constexpr T egamma_v<T> // 欧拉常数γ
template<floating_point T> inline constexpr T phi_v<T> // 黄金分割比Φ
inline constexpr double e = e_v<double>
inline constexpr double log2e = log2e_v<double>
inline constexpr double log10e = log10e_v<double>
inline constexpr double pi = pi_v<double>
inline constexpr double inv_pi = pi_v<double>
inline constexpr double inv_sqrtpi = pi_v<double>
inline constexpr double ln2 = ln2_v<double>
inline constexpr double ln10 = ln10_v<double>
inline constexpr double sqrt2 = sqrt2_v<double>
inline constexpr double sqrt3 = sqrt3_v<double>
inline constexpr double inv_sqrt3 = sqrt3_v<double>
inline constexpr double egamma = egamma_v<double>
inline constexpr double phi = phi_v<double>

以下是 std::numbers 中包含的常量列表:

常量/模板名称描述示例值(近似)
e_v数学常数 e(自然对数的底数)2.718281828459045
log2e_v以 2 为底的 e 的对数(log₂(e))1.4426950408889634
log10e_v以 10 为底的 e 的对数(log₁₀(e))0.4342944819032518
pi_v数学常数 π(圆周率)3.141592653589793
inv_pi_v1/π(π的倒数)0.318309886183121
inv_sqrtpi_v1/√π(π的平方根的倒数)0.5641895835477563
ln2_v自然对数底数 2 的对数(ln(2))0.6931471805599453
ln10_v自然对数底数 10 的对数(ln(10))2.302585092994046
sqrt2_v√2(根号 2)1.4142135623730951
sqrt3_v√3(根号 3)1.7320508075688772
inv_sqrt3_v1/√3(根号 3 的倒数)0.5773502691896257
egamma_v欧拉-马歇罗尼常数 γ(Euler-Mascheroni constant)0.5772156649015329
phi_v黄金比例 Φ((1 + √5) / 2)1.618033988749895
e常量 e (等价于 e_v<double>)2.718281828459045
log2e常量 log₂(e) (等价于 log2e_v<double>)1.4426950408889634
log10e常量 log₁₀(e) (等价于 log10e_v<double>)0.4342944819032518
pi常量 π (等价于 pi_v<double>)3.141592653589793
inv_pi常量 1/π (等价于 inv_pi_v<double>)0.318309886183121
inv_sqrtpi常量 1/√π (等价于 inv_sqrtpi_v<double>)0.5641895835477563
ln2常量 ln(2) (等价于 ln2_v<double>)0.6931471805599453
ln10常量 ln(10) (等价于 ln10_v<double>)2.302585092994046
sqrt2常量 √2 (等价于 sqrt2_v<double>)1.4142135623730951
sqrt3常量 √3 (等价于 sqrt3_v<double>)1.7320508075688772
inv_sqrt3常量 1/√3 (等价于 inv_sqrt3_v<double>)0.5773502691896257
egamma常量 γ (欧拉-马歇罗尼常数) (等价于 egamma_v<double>)0.5772156649015329
phi常量黄金比例 Φ (等价于 phi_v<double>)1.618033988749895

这些常量和变量模板涵盖了圆周率、自然对数底、黄金比例等常用的数学常数,并通过不同类型的变量模板提供精度选项,如 float、double 和 long double。

实例

#include <iostream>
#include <iomanip>
#include <numbers>
#include <cmath>  // 用于标准数学函数 sin, cos, log 等

using namespace std;

int main()
{
    // 使用默认的 double 类型常数
    cout << fixed << setprecision(15); // 设置所有输出为 15 位小数

    // 打印圆周率 π 的值
    cout << "圆周率 pi 的值是: " << numbers::pi << endl;

    // 打印自然对数的底数 e 的值
    cout << "自然常数 e 的值是: " << numbers::e << endl;

    // 打印根号2 (sqrt2) 的值
    cout << "根号2 (sqrt2) 的值是: " << numbers::sqrt2 << endl;

    // 打印根号3 (sqrt3) 的值
    cout << "根号3 (sqrt3) 的值是: " << numbers::sqrt3 << endl;

    // 打印黄金比例 phi 的值
    cout << "黄金比例 phi 的值是: " << numbers::phi << endl;

    // 打印欧拉-马歇罗尼常数 egamma 的值
    cout << "欧拉-马歇罗尼常数 egamma 的值是: " << numbers::egamma << endl;

    // 打印 1/π (inv_pi) 的值
    cout << "1/π (inv_pi) 的值是: " << numbers::inv_pi << endl;

    // 打印 1/√π (inv_sqrtpi) 的值
    cout << "1/√π (inv_sqrtpi) 的值是: " << numbers::inv_sqrtpi << endl;

    // 打印以 2 为底的 e 的对数 log2e 的值
    cout << "以 2 为底的 e 的对数 log2e 的值是: " << numbers::log2e << endl;

    // 打印以 10 为底的 e 的对数 log10e 的值
    cout << "以 10 为底的 e 的对数 log10e 的值是: " << numbers::log10e << endl;

    // 打印 sin(π/2) 的值
    cout << "sin(π/2) 的值是: " << sin(numbers::pi / 2) << endl;

    // 打印 cos(π) 的值
    cout << "cos(π) 的值是: " << cos(numbers::pi) << endl;

    // 打印 ln(e) 的值
    cout << "ln(e) 的值是: " << log(numbers::e) << endl;

    // 演示使用不同的数据类型
    float pi_f = numbers::pi_v<float>;  // 使用 float 类型的 pi
    cout << "\n使用 float 类型的 pi: " << setprecision(7) << pi_f << endl; // 输出 7 位小数
   
    long double pi_ld = numbers::pi_v<long double>;  // 使用 long double 类型的 pi
    cout << "使用 long double 类型的 pi: " << setprecision(21) << pi_ld << endl; // 输出 21 位小数

    // 计算不同精度的值
    cout << "\nsin(π/2) 使用 double: " << sin(numbers::pi / 2) << endl;
    cout << "sin(π/2) 使用 float: " << sin(static_cast<float>(numbers::pi) / 2) << endl;
    cout << "sin(π/2) 使用 long double: " << sin(static_cast<long double>(numbers::pi) / 2) << endl;

    return 0;
}

代码解析:

  1. 格式化输出:

    • 使用 fixedsetprecision() 来确保输出的小数点后有固定的位数。这里默认输出 15 位小数,但也可以为每个不同的数据类型设置不同的精度。
  2. 计算常见数学函数:

    • 计算了 sin(π/2)cos(π)ln(e) 等常见数学函数,并使用 cmath 中的函数(例如 sincoslog)来展示如何使用数学常数。
  3. 不同数据类型的精度:

    • 使用 numbers::pi_v<float>numbers::pi_v<long double> 来展示不同类型的常数。对于 floatlong double,可以使用不同的精度输出。
  4. 使用不同类型的计算:

    • 在计算 sin 时,展示了如何用不同精度的类型进行计算,演示了 floatdoublelong double 在相同数学表达式下的差异。

输出:

圆周率 pi 的值是: 3.141592653589793
自然常数 e 的值是: 2.718281828459045
根号2 (sqrt2) 的值是: 1.414213562373095
根号3 (sqrt3) 的值是: 1.732050807568877
黄金比例 phi 的值是: 1.618033988749895
欧拉-马歇罗尼常数 egamma 的值是: 0.5772156649015329
1/π (inv_pi) 的值是: 0.318309886183121
1/√π (inv_sqrtpi) 的值是: 0.5641895835477563
以 2 为底的 e 的对数 log2e 的值是: 1.4426950408889634
以 10 为底的 e 的对数 log10e 的值是: 0.4342944819032518
sin(π/2) 的值是: 1
cos(π) 的值是: -1
ln(e) 的值是: 1

使用 float 类型的 pi: 3.1415927
使用 long double 类型的 pi: 3.141592653589793238462643
sin(π/2) 使用 double: 1
sin(π/2) 使用 float: 1
sin(π/2) 使用 long double: 1