私は現在、数値計算を行う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
最後の2つのケースで提供される8バイトは、1.0E200を保持するのに十分であると理解しています。これは、同じプログラムが-fsingle-precision-constantなしでコンパイルされる次の出力でサポートされる理論です。
~/path$ g++ test.cpp && ./a.out
8
1e+200
16
1e+200
8
1e+200
8
1e+200
上記の例で提案されている考えられる回避策は、元々倍精度を使用するつもりだったすべての場所で4倍精度の浮動小数点リテラルを使用し、ライブラリなどで必要な場合はいつでも倍精度にキャストすることです。ただし、これは少し無駄に感じます。
他に何ができますか?