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 name | Description | Example values (approximate) |
|---|---|---|
e_v | Mathematical constant e (base of natural logarithms) | 2.718281828459045 |
log2e_v | Logarithm of e to base 2 (log₂(e)) | 1.4426950408889634 |
log10e_v | Logarithm of e to base 10 (log₁₀(e)) | 0.4342944819032518 |
pi_v | Mathematical constant π (pi) | 3.141592653589793 |
inv_pi_v | 1/π (the reciprocal of π) | 0.318309886183121 |
inv_sqrtpi_v | 1/√π (reciprocal of the square root of π) | 0.5641895835477563 |
ln2_v | Natural logarithm of 2 (ln(2)) | 0.6931471805599453 |
ln10_v | Natural 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_v | 1/√3 (reciprocal of the square root of 3) | 0.5773502691896257 |
egamma_v | Euler-Mascheroni constant γ | 0.5772156649015329 |
phi_v | Golden ratio Φ ((1 + √5) / 2) | 1.618033988749895 |
e | Constant e (equivalent toe_v<double>) | 2.718281828459045 |
log2e | Constant log₂(e) (equivalent tolog2e_v<double>) | 1.4426950408889634 |
log10e | Constant log₁₀(e) (equivalent tolog10e_v<double>) | 0.4342944819032518 |
pi | Constant π (equivalent topi_v<double>) | 3.141592653589793 |
inv_pi | Constant 1/π (equivalent toinv_pi_v<double>) | 0.318309886183121 |
inv_sqrtpi | Constant 1/√π (equivalent toinv_sqrtpi_v<double>) | 0.5641895835477563 |
ln2 | Constant ln(2) (equivalent toln2_v<double>) | 0.6931471805599453 |
ln10 | Constant ln(10) (equivalent toln10_v<double>) | 2.302585092994046 |
sqrt2 | Constant √2 (equivalent tosqrt2_v<double>) | 1.4142135623730951 |
sqrt3 | Constant √3 (equivalent tosqrt3_v<double>) | 1.7320508075688772 |
inv_sqrt3 | Constant 1/√3 (equivalent toinv_sqrt3_v<double>) | 0.5773502691896257 |
egamma | Constant γ (Euler–Mascheroni constant) (equivalent toegamma_v<double>) | 0.5772156649015329 |
phi | Constant 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 <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:
- Usage
fixedandsetprecision()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:
- computed
sin(π/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:
- Usage
numbers::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 computing
sinwhen ..., 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 <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 <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 <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 <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;
}