我目前正在从事一个进行数值计算的 C++ 项目。绝大多数代码使用单精度浮点值,并且可以很好地使用它。因此,我使用编译器标志来使基本的浮点文字单精度而不是双精度,这是默认的。我发现这使表达式更易于阅读,而且我不必担心在某处忘记“f”。但是,我时不时需要双精度计算提供的额外精度,我的问题是如何将双精度文字放入这样的表达式中。到目前为止,我尝试过的每种方法都首先将值存储在单精度变量中,然后将截断的值转换为双精度值。不是我想要的。
下面给出了我迄今为止尝试过的一些方法。
#include <iostream>
int main()
{
std::cout << sizeof(1.0E200) << std::endl;
std::cout << 1.0E200 << std::endl;
std::cout << sizeof(1.0E200L) << std::endl;
std::cout << 1.0E200L << std::endl;
std::cout << sizeof(double(1.0E200)) << std::endl;
std::cout << double(1.0E200) << std::endl;
std::cout << sizeof(static_cast<double>(1.0E200)) << std::endl;
std::cout << static_cast<double>(1.0E200) << std::endl;
return 0;
}
使用单精度常量运行会产生以下结果。
~/path$ g++ test.cpp -fsingle-precision-constant && ./a.out
test.cpp:6:3: warning: floating constant exceeds range of ‘float’ [-Woverflow]
test.cpp:7:3: warning: floating constant exceeds range of ‘float’ [-Woverflow]
test.cpp:12:3: warning: floating constant exceeds range of ‘float’ [-Woverflow]
test.cpp:13:3: warning: floating constant exceeds range of ‘float’ [-Woverflow]
test.cpp:15:3: warning: floating constant exceeds range of ‘float’ [-Woverflow]
test.cpp:16:3: warning: floating constant exceeds range of ‘float’ [-Woverflow]
4
inf
16
1e+200
8
inf
8
inf
据我了解,最后两种情况提供的 8 个字节应该足以容纳 1.0E200,这是由以下输出支持的理论,其中相同的程序在没有 -fsingle-precision-constant 的情况下编译。
~/path$ g++ test.cpp && ./a.out
8
1e+200
16
1e+200
8
1e+200
8
1e+200
上述示例建议的一种可能的解决方法是在我最初打算使用双精度的任何地方使用四精度浮点文字,并在库等需要时转换为双精度。但是,这感觉有点浪费。
我还可以做些什么?