[英]C++17 Hexidecimal floating point literal single precision suffix conflict?
[英]Is there a floating point literal suffix in C++ to make a number double precision?
我目前正在研究一個進行數值計算的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
上面示例建議的一種可能的解決方法是在我最初打算使用雙精度的地方使用四倍精度浮點文字,並在庫等需要時轉換為雙精度。 但是,這感覺有點浪費。
我還可以做些什么?
就像馬克所說的那樣,標准說它是一個雙倍,除非它后跟一個f。
標准背后有充分的理由,並且為方便起見,使用編譯器標志繞過它是不好的做法。
所以,正確的方法是:
它可能不是您正在尋找的答案,但如果您關心代碼庫的使用壽命,這是您應該使用的方法。
如果您閱讀2.13.3 / 1,您會看到:
除非后綴明確指定,否則浮動文字的類型為double。 后綴f和F指定float,后綴l和L指定long double。
換句話說,如果將默認值更改為float
,則沒有后綴為文字浮點常量指定double
。 不幸的是,在這種情況下,你不可能擁有兩全其美的優勢。
如果你能負擔得起GCC 4.7或Clang 3.1,請使用用戶定義的文字:
double operator "" _d(long double v) { return v; }
用法:
std::cout << sizeof(1.0E200_d) << std::endl;
std::cout << 1.0E200_d << std::endl;
結果:
8
1e+200
你不能定義自己的后綴,但可能是宏
#define D(x) (double(x##L))
會對你有用。 編譯器應該只發出一個雙常量,並且在我的系統上看起來是-O2
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.