C++ Standard Library<numbers>

Before C++20, we usually wrote mathematical constants like this:

const double PI = 3.14159265358979323846;

The problem is very obvious:Precision was written arbitrarily, inconsistent, error-prone, and type-unsafe./p>

C++20 officially introduced#include <numbers>, providing a standardized set of mathematical constants, with precision and type correctness guaranteed by the compiler.

std::numbersIt is a standard library module introduced in C++20, mainly used to provide a set of commonly used mathematical constants, serving as a standard repository of mathematical and physical constants.

std::numbersLocated at<numbers>in the header file, and contains many mathematical constants, covering common constants such as pi, the base of natural logarithms, the golden ratio, etc.

Using these constants in C++ can improve code readability, precision, and efficiency, avoiding repeated definitions and manual input of constant values.

std::numbersAdvantages compared with traditional writing:

Dimension Traditional approach <numbers>
Precision Ad hoc Standard high precision
Type Fixed Automatic matching
Readability Average Clear semantics
Compile-time constant Not necessarily Definitely
Standardization Poor Standard library level

Constants contained in the std::numbers module

The std::numbers namespace contains the following members:

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>

The following is a list of constants contained in std::numbers:

Constant/template nameDescriptionExample values (approximate)
e_vMathematical constant e (base of natural logarithms)2.718281828459045
log2e_vLogarithm of e to base 2 (log₂(e))1.4426950408889634
log10e_vLogarithm of e to base 10 (log₁₀(e))0.4342944819032518
pi_vMathematical constant π (pi)3.141592653589793
inv_pi_v1/π (the reciprocal of π)0.318309886183121
inv_sqrtpi_v1/√π (reciprocal of the square root of π)0.5641895835477563
ln2_vNatural logarithm of 2 (ln(2))0.6931471805599453
ln10_vNatural logarithm of 10 (ln(10))2.302585092994046
sqrt2_v√2 (square root of 2)1.4142135623730951
sqrt3_v√3 (square root of 3)1.7320508075688772
inv_sqrt3_v1/√3 (reciprocal of the square root of 3)0.5773502691896257
egamma_vEuler-Mascheroni constant γ0.5772156649015329
phi_vGolden ratio Φ ((1 + √5) / 2)1.618033988749895
eConstant e (equivalent toe_v<double>)2.718281828459045
log2eConstant log₂(e) (equivalent tolog2e_v<double>)1.4426950408889634
log10eConstant log₁₀(e) (equivalent tolog10e_v<double>)0.4342944819032518
piConstant π (equivalent topi_v<double>)3.141592653589793
inv_piConstant 1/π (equivalent toinv_pi_v<double>)0.318309886183121
inv_sqrtpiConstant 1/√π (equivalent toinv_sqrtpi_v<double>)0.5641895835477563
ln2Constant ln(2) (equivalent toln2_v<double>)0.6931471805599453
ln10Constant ln(10) (equivalent toln10_v<double>)2.302585092994046
sqrt2Constant √2 (equivalent tosqrt2_v<double>)1.4142135623730951
sqrt3Constant √3 (equivalent tosqrt3_v<double>)1.7320508075688772
inv_sqrt3Constant 1/√3 (equivalent toinv_sqrt3_v<double>)0.5773502691896257
egammaConstant γ (Euler–Mascheroni constant) (equivalent toegamma_v<double>)0.5772156649015329
phiConstant golden ratio Φ (equivalent tophi_v<double>)1.618033988749895

These constants and variable templates cover commonly used mathematical constants such as pi, natural logarithm base, golden ratio, and provide precision options through variable templates of different types, such as float, double, and long double.

Example

#include <iostream>
#include <iomanip>
#include <numbers>
#include <cmath> // for standard math functions sin, cos, log, etc.

using namespace std;

int main()
{
    // Use default double type constants
    cout << fixed << setprecision(15); // Set all output to 15 decimal places

    // Print the value of π (pi)
    cout << "The value of pi is: " << numbers::pi << endl;

    // Print the value of e (base of natural logarithm)
    cout << "The value of natural constant e is: " << numbers::e << endl;

    // Print the value of square root of 2 (sqrt2)
    cout << "The value of square root of 2 (sqrt2) is: " << numbers::sqrt2 << endl;

    // Print the value of square root of 3 (sqrt3)
    cout << "The value of square root of 3 (sqrt3) is: " << numbers::sqrt3 << endl;

    // Print the value of golden ratio phi
    cout << "The value of golden ratio phi is: " << numbers::phi << endl;

    // Print the value of the Euler-Mascheroni constant egamma
    cout << "The value of the Euler-Mascheroni constant egamma is: " << numbers::egamma << endl;

    // Print the value of 1/π (inv_pi)
    cout << "The value of 1/π (inv_pi) is: " << numbers::inv_pi << endl;

    // Print the value of 1/√π (inv_sqrtpi)
    cout << "The value of 1/√π (inv_sqrtpi) is: " << numbers::inv_sqrtpi << endl;

    // Print the value of log2e, the base-2 logarithm of e
    cout << "The value of log2e, the base-2 logarithm of e, is: " << numbers::log2e << endl;

    // Print the value of log10e, the base-10 logarithm of e
    cout << "The value of log10e, the base-10 logarithm of e, is: " << numbers::log10e << endl;

    // Print the value of sin(π/2)
    cout << "The value of sin(π/2) is: " << sin(numbers::pi / 2) << endl;

    // Print the value of cos(π)
    cout << "The value of cos(π) is: " << cos(numbers::pi) << endl;

    // Print the value of ln(e)
    cout << "The value of ln(e) is: " << log(numbers::e) << endl;

    // Demonstrate the use of different data types
    float pi_f = numbers::pi_v<float>;  // Use pi of type float
    cout << "\nUse pi of type float: " << setprecision(7) << pi_f << endl; // Output 7 decimal places
   
    long double pi_ld = numbers::pi_v<long double>;  // Use pi of type long double
    cout << "Use pi of type long double: " << setprecision(21) << pi_ld << endl; // Output 21 decimal places

    // Compute values with different precisions
    cout << "\nsin(π/2) using double: " << sin(numbers::pi / 2) << endl;
    cout << "sin(π/2) using float: " << sin(static_cast<float>(numbers::pi) / 2) << endl;
    cout << "sin(π/2) using long double: " << sin(static_cast<long double>(numbers::pi) / 2) << endl;

    return 0;
}

Code Analysis:

Formatted output:

  • Usagefixedandsetprecision()to ensure a fixed number of digits after the decimal point in the output. Here, 15 decimal places are output by default, but different precision can also be set for each different data type.

Compute common mathematical functions:

  • computedsin(π/2)、cos(π)andln(e)and other common mathematical functions, and usecmathfunctions in (for examplesin、cosandlog) to demonstrate how to use mathematical constants.

Precision for different data types:

  • Usagenumbers::pi_v<float>andnumbers::pi_v<long double>to demonstrate different types of constants. Forfloatandlong double, you can output with different precision.

Computations using different types:

  • When computingsinwhen ..., it demonstrates how to perform calculations using types of different precision, illustratingfloat、doubleandlong doubledifferences under the same mathematical expression.

Output:

圆周率 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

Usage examples

The following examples cover<numbers>The most commonly used constants; the code can be compiled and run directly. Remember to add a standard parameter-std=c++20:

g++ -std=c++20 main.cpp -o main

Example 1: Basic usage

Calculating the area / circumference of a circle using π:

Example

#include <iostream>
#include <numbers> // includes math constants
#include <cmath> // includes math functions such as pow

using namespace std;
using namespace std::numbers;  // Simplify constant calls (optional)

int main() {
    // The circle's radius
    double r = 5.0;

    // 1. Calculate the circle's circumference: 2 * π * r
    double circumference = 2 * pi * r;  // Use double-precision π directly
    cout << "Radius is " << r << ", circumference: " << circumference << endl;  // Output: 31.4159

    // 2. Calculate the circle's area: π * r²
    double area = pi * pow(r, 2);
    cout << "Radius is " << r << ", area: " << area << endl;  // Output: 78.5398

    // 3. High-precision version (long double)
    long double r_ld = 5.0L;
    long double area_ld = pi_v<long double> * powl(r_ld, 2);  // powl is the long double version of pow
    cout << "High-precision circle area: " << area_ld << endl;  // Outputs a more precise 78.53981633974483...

    return 0;
}

Example 2: Constant e

Natural constant e and exponential calculations:

Example

#include <iostream>
#include <numbers>
#include <cmath>

using namespace std;
using namespace std::numbers;

int main() {
    // Natural exponential calculation: e^x (the exp function is the exponential function in cmath)
    double x = 2.0;
    double exp_result = exp(x);          // Manually compute e^2
    double exp_result_direct = pow(e, x); // Compute e^2 using numbers::e
    cout << "e^2 = " << exp_result << endl;          // Output: 7.38906
    cout << "e^2 (direct calculation) = " << exp_result_direct << endl;  // Results are consistent

    return 0;
}

Example 3: Golden ratio

Application of the golden ratio φ:

Example

#include <iostream>
#include <numbers>

using namespace std;
using namespace std::numbers;

int main() {
    // Golden ratio: when length/width = φ, it is a golden rectangle
    double width = 10.0;
    double golden_height = width * phi;  // Height of the golden rectangle
    cout << "Width is " << width << ", the height of the golden rectangle: " << golden_height << endl;  // Output: 16.1803

    // Verify the mathematical definition of φ: φ = (1 + √5)/2
    double phi_manual = (1 + sqrt(5.0)) / 2;
    cout << "Manually calculated golden ratio: " << phi_manual << endl;  // Consistent with numbers::phi

    return 0;
}

Example 4: Floating-point types

Adaptation of constants for different floating-point types:

Example

#include <iostream>
#include <numbers>
#include <iomanip> // used to set output precision

using namespace std;

int main() {
    // Set high-precision output (display 15 decimal places)
    cout << fixed << setprecision(15);

    // float version of π (single precision)
    float pi_float = std::numbers::pi_v<float>;
    cout << "float π: " << pi_float << endl;  // Output: 3.141592741012573

    // double version of π (double precision, default)
    double pi_double = std::numbers::pi;
    cout << "double π: " << pi_double << endl;  // Output: 3.141592653589793

    // long double version of π (high precision)
    long double pi_long_double = std::numbers::pi_v<long double>;
    cout << "long double π: " << pi_long_double << endl;  // Outputs the more precise value 3.1415926535897932385...

    return 0;
}
other extensions