C/C++数值计算时常需要用到诸如Pi、自然常数e等数学常量,但是这些常量并没有在标准C/C++中定义。幸运的是,现代化的C/C++ math.h
都定义了如下常用的数学常量:
符号 | 表达式 | 值 |
---|---|---|
M_E |
e | 2.71828182845904523536 |
M_LOG2E |
log2(e) | 1.44269504088896340736 |
M_LOG10E |
log10(e) | 0.434294481903251827651 |
M_LN2 |
ln(2) | 0.693147180559945309417 |
M_LN10 |
ln(10) | 2.30258509299404568402 |
M_PI |
pi | 3.14159265358979323846 |
M_PI_2 |
pi/2 | 1.57079632679489661923 |
M_PI_4 |
pi/4 | 0.785398163397448309616 |
M_1_PI |
1/pi | 0.318309886183790671538 |
M_2_PI |
2/pi | 0.636619772367581343076 |
M_2_SQRTPI |
2/sqrt(pi) | 1.12837916709551257390 |
M_SQRT2 |
sqrt(2) | 1.41421356237309504880 |
M_SQRT1_2 |
1/sqrt(2) | 0.707106781186547524401 |
需要注意的是,Windows平台上的MSVC编译器,使用这些数学常量需要先定义 _USE_MATH_DEFINES
宏,否则会报未定义的错误:
#define _USE_MATH_DEFINES // C++
#include <cmath>
#define _USE_MATH_DEFINES // C
#include <math.h>
到了C++20,事情有了新的变化:新增的 numbers
头文件将这些常量都定义了,并且无需以 M_
修饰。得益于C++ 14中新增的 变量模板 特性,这些数学常量都以模板的形式定义:
#include <iostream> #include <iomanip> #include <numbers> #include <limits> int main() { // 输出单精度的pi std::cout << "float pi: " << std::setprecision(std::numeric_limits<float>::digits10) << std::numbers::pi_v<float> << std::endl; // std::numbers::pi 是double类型的特化 // std::numbers::pi 等同于 std::numbers::pi_v<double> std::cout << "double pi: " << std::setprecision(std::numeric_limits<double>::digits10) << std::numbers::pi << std::endl; // 双精度的ln(2) std::cout << "double ln2: " << std::numbers::ln2 << std::endl; return 0; }
至此,我们可以放心地使用数学常量而无需担心跨平台问题了。
参考
2. Predefined Mathematical Constants
4. C++模板编程