我注意到所有数学常数都声明为double,这在某些不存在双精度单位的平台上导致转换问题。GCC标准库中是否有一个开关可以自动向下转换或使用单独的定义?
正如下面 Bob 提到的,从 C++20 开始,我们有了std::numbers。这将导致:
#include <numbers>
...
double PI = std::number::pi;
float PIF = std::number::pi_v<float>;
...
Run Code Online (Sandbox Code Playgroud)
尽管 Boost 数字预定义了更多数字,但随着时间的推移,这可能会是前进的方式。
艾伦·斯特罗克(Alan Stroke)的评论有一个提升常量的链接,我认为它给出了最好的答案。使用:
#include <boost/math/constants/constants.hpp>
...
boost::math::float_constants::pi
...
Run Code Online (Sandbox Code Playgroud)
同样,您可以使用double和long double常量:
...
boost::math::double_constants::pi
...
boost::math::long_double_constants::pi
...
Run Code Online (Sandbox Code Playgroud)
在内部,Boost 使用一个宏,其作用相当于:
M_PI ## F
Run Code Online (Sandbox Code Playgroud)
换句话说,它告诉编译器将该浮点文字读取为 afloat而不是 a double。
如果您更喜欢使用类似 C 的常量,您也可以这样声明:
#define M_PIF 3.141592653589793238462643383279502884e+00F
Run Code Online (Sandbox Code Playgroud)
请注意F数字末尾的 。
这几乎就是 boost 内部所做的事情。这实际上可能是您情况下的最佳解决方案,因为您说您使用的某些编译器根本不支持 double (因此仅使用M_PI可能已经是一个问题,并且 boost 库声明了所有三种类型:float, double,和long double)。
如有必要,可以降低值的精度,以防编译器抱怨文字包含太多数字。
您也可以简单地转换默认值,但是,编译器仍然需要在某种程度上正确支持 double:
...
static_cast<float>(M_PI)
...
Run Code Online (Sandbox Code Playgroud)
这样一个简单的转换将阻止编译器将数字转换为双精度,然后再转换回浮点,这在大多数情况下会使运行速度更快。
请注意,对于某些数字,强制转换可能不会产生与使用F后缀相同的值。然而,对于M_PI,它恰好工作得很好:
// create pi.cpp
#include <iostream>
int main(int argc, char * argv[])
{
float pi1 = 3.14159265358979323846;
float pi2 = 3.14159265358979323846f;
std::cout << "pi1: " << pi1 << "\n";
std::cout << "pi2: " << pi2 << "\n";
std::cout << "pi1 == pi2? " << std::boolalpha << (pi1 == pi2) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和输出:
$ g++ -std=c++17 pi.cpp
$ ./a.out
pi1: 3.14159
pi2: 3.14159
pi1 == pi2? true
Run Code Online (Sandbox Code Playgroud)
好吧,至少在英特尔处理器上是这样。无论如何,差异应该是一点点,这在大多数情况下可能不是问题。
| 归档时间: |
|
| 查看次数: |
2084 次 |
| 最近记录: |