我注意到所有的数学常数都被声明为双精度的,这在一些没有双精度单位的平台上会导致转换问题。GCC的标准库中是否有一个开关,可以自动向下转换或使用单独的定义?
ee7vknir1#
正如Bob在下面提到的,由于C++20,我们有std::numbers。这将导致:
#include <numbers> ... double PI = std::number::pi; float PIF = std::number::pi_v<float>; ...
随着时间的推移,这可能是前进的方式,尽管Boost数字有更多的预定义数字。
Alan Stroke的评论中有一个boost constants的链接,我认为它给出了最佳答案。用途:
#include <boost/math/constants/constants.hpp> ... boost::math::float_constants::pi ...
同样,您可以使用double和long double常量:
double
long double
... boost::math::double_constants::pi ... boost::math::long_double_constants::pi ...
在内部,Boost使用一个宏,它执行以下等效操作:
M_PI ## F
换句话说,它告诉编译器将该浮点文字读取为float,而不是double。
float
如果你更喜欢使用 * 类C常量 *,你也可以这样声明:
#define M_PIF 3.141592653589793238462643383279502884e+00F
F
这基本上就是boost在内部所做的事情。这可能实际上是最适合您的情况的解决方案,因为您说您使用的一些编译器根本不支持double(因此,仅仅使用M_PI可能已经是一个开始的问题,并且boost库声明了所有三种类型:float、double和long double)中的一个或多个。如果编译器抱怨常值的数字太多,可以视需要降低值的精确度。
M_PI
您也可以简单地转换默认值,但是编译器仍然需要在一定程度上正确支持double:
... static_cast<float>(M_PI) ...
这样一个简单的类型转换将阻止编译器将您的数字转换为double,然后再转换回float,这在大多数情况下会使运行速度更快。请注意,对于某些数字,强制转换可能不会产生与使用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; }
而输出:
$ g++ -std=c++17 pi.cpp $ ./a.out pi1: 3.14159 pi2: 3.14159 pi1 == pi2? true
好吧,至少在英特尔处理器上。无论如何,两者的区别应该是一位,这在大多数情况下可能不是一个问题。
1条答案
按热度按时间ee7vknir1#
C数字(C20起)
正如Bob在下面提到的,由于C++20,我们有std::numbers。这将导致:
随着时间的推移,这可能是前进的方式,尽管Boost数字有更多的预定义数字。
提升数字
Alan Stroke的评论中有一个boost constants的链接,我认为它给出了最佳答案。用途:
同样,您可以使用
double
和long double
常量:在内部,Boost使用一个宏,它执行以下等效操作:
换句话说,它告诉编译器将该浮点文字读取为
float
,而不是double
。宏(不推荐)
如果你更喜欢使用 * 类C常量 *,你也可以这样声明:
F
。*这基本上就是boost在内部所做的事情。这可能实际上是最适合您的情况的解决方案,因为您说您使用的一些编译器根本不支持double(因此,仅仅使用
M_PI
可能已经是一个开始的问题,并且boost库声明了所有三种类型:float
、double
和long double
)中的一个或多个。如果编译器抱怨常值的数字太多,可以视需要降低值的精确度。
演员阵容
您也可以简单地转换默认值,但是编译器仍然需要在一定程度上正确支持double:
这样一个简单的类型转换将阻止编译器将您的数字转换为double,然后再转换回float,这在大多数情况下会使运行速度更快。
请注意,对于某些数字,强制转换可能不会产生与使用
F
后缀相同的值。但是,对于M_PI
,它恰好可以正常工作:而输出:
好吧,至少在英特尔处理器上。无论如何,两者的区别应该是一位,这在大多数情况下可能不是一个问题。