倍精度と単精度の違いについて読みました。しかし、ほとんどの場合、float
とdouble
は互換性があるようです。つまり、どちらか一方を使用しても結果に影響はないようです。これは本当にそうでしょうか? float と double はどのような場合に互換性があるのでしょうか? それらの違いは何ですか?
ベストアンサー1
大きな違い。
名前の通り、double
2倍の精度を持つfloat
[1]。一般に、a はdouble
15桁の精度を持ちますが、 はfloat
7桁の精度を持ちます。
桁数の計算方法は次のとおりです。
double
52 個の仮数ビット + 1 個の隠しビット: log(2 53 )÷log(10) = 15.95 桁
float
23の仮数ビット+1の隠しビットを持つ: log(2 24 )÷log(10) = 7.22桁
この精度の低下は、例えば繰り返し計算を行う際に、より大きな切り捨て誤差が蓄積されることにつながる可能性がある。
float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.7g\n", b); // prints 9.000023
その間
double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.15g\n", b); // prints 8.99999999999996
また、float の最大値は約 です3e38
が、double は約 なので1.7e308
、 を使用すると、60 の階乗を計算するなどの単純な場合float
よりもはるかに簡単に「無限大」(つまり、特殊な浮動小数点数) に達する可能性がありdouble
ます。
テスト中に、いくつかのテスト ケースにこれらの巨大な数値が含まれる場合があり、浮動小数点数を使用するとプログラムが失敗する可能性があります。
もちろん、それでもdouble
十分正確でない場合もあります。そのため、long double
[1]になることもあります(上記の例では、Mac では 9.0000000000000000066 になります)。ただし、すべての浮動小数点型は丸め誤差int
の影響を受けるため、精度が非常に重要な場合 (例: 金銭処理) は、または分数クラスを使用する必要があります。
+=
さらに、浮動小数点数を合計するのに を使用しないでください。誤差がすぐに蓄積されます。Pythonを使用している場合は を使用してくださいfsum
。それ以外の場合は、 を実装してみてください。カハン加算アルゴリズム。
[1]: CおよびC++標準では、、およびの表現は指定されていません。3float
つすべてがIEEE倍精度として実装されている可能性があります。ただし、ほとんどのアーキテクチャ(gcc、MSVC、x86、x64、ARM)では、はIEEE単精度浮動小数点数(binary32)であり、はIEEE倍精度浮動小数点数(binary64)です。double
long double
float
double