web-dev-qa-db-ja.com

doubleまたはfloatを使用する必要がありますか?

C++で一方を使用する場合の利点と欠点は何ですか?

78
AraK

真の答えを知りたい場合は、 すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと を読んでください。

要するに、doubleはその表現でより高い精度を許可しますが、特定の計算ではより大きなエラー。 「正しい」選択肢は次のとおりです。必要なだけの精度を使用しますが、それ以上は使用しませんおよび正しいアルゴリズムを選択します

多くのコンパイラーは、とにかく「非厳密」モードで拡張浮動小数点演算を実行します(つまり、ハードウェアで利用可能なより広い浮動小数点型を使用します(80ビットおよび128ビット浮動など)。これも考慮に入れる必要があります。実際には、速度の違いをほとんど見ることができません-とにかくハードウェアのネイティブです。

97
J-16 SDiZ

特別な理由がない限り、doubleを使用します。

おそらく驚くべきことに、C(およびC++)の「通常の」浮動小数点型であるdoubleではなくfloatです。 sinlogなどの標準の数学関数は、引数としてdoubleを取り、doubleを返します。プログラムで.14と記述するときのような通常の浮動小数点リテラルは、double型を持ちます。浮かない。

典型的な最新のコンピューターでは、倍精度は浮動小数点数と同じかそれより高速であるため、通常、大規模な計算であってもパフォーマンスは考慮すべき要素ではありません。 (そして、それらはlarge計算である必要があります。そうでない場合、パフォーマンスが気に入らないはずです。私の新しいi7デスクトップコンピューターは、倍の60億の乗算を実行できます。 1秒で。)

質問には文脈がないため、この質問に答えることは不可能です。選択に影響する可能性のあるものを次に示します。

  1. Float、double、long doubleのコンパイラ実装。 C++標準の状態:

    浮動小数点型には、float、double、およびlong doubleの3つがあります。 double型は少なくともfloatと同じ精度を提供し、long double型は少なくともdoubleと同じ精度を提供します。

    したがって、3つすべてをメモリ内で同じサイズにすることができます。

  2. FPUの存在。すべてのCPUにFPUがあるわけではなく、浮動小数点型がエミュレートされたり、浮動小数点型がサポートされないことがあります。

  3. FPUアーキテクチャ。 IA32のFPUは内部で80ビットです。32ビットと64ビットのフロートは、ロード時に80ビットに拡張され、ストア時に削減されます。 4つの32ビットフロートまたは2つの64ビットフロートを並行して実行できるSIMDもあります。 SIMDの使用は標準では定義されていないため、SIMDを使用できるかどうかを判断するためのより複雑な分析を行うコンパイラー、または特別な関数(ライブラリーまたは組み込み関数)の使用を必要とするコンパイラーが必要です。 80ビットの内部形式の結果は、データをRAM(したがって精度が失われる)に保存する頻度によってわずかに異なる結果が得られることです。このため、コンパイラーは最適化を行いません。特に浮動小数点コード。

  4. メモリ帯域幅。 doubleがfloatよりも多くのストレージを必要とする場合、データの読み取りに時間がかかります。それが素朴な答えです。最新のIA32では、データの送信元にすべて依存しています。 L1キャッシュにある場合、データが単一のキャッシュラインから来る場合、負荷は無視できます。複数のキャッシュラインにまたがる場合、わずかなオーバーヘッドがあります。 L2からの場合は時間がかかります。RAMの場合はさらに長くなり、最後にディスク上にある場合は非常に時間がかかります。floatまたはdoubleの選択はそれほど重要ではありません。大量のシーケンシャルデータで小さな計算を行いたい場合は、小さなデータタイプが望ましいです。小さなデータセットで多くの計算を行うと、重要なデータタイプで大きなデータタイプを使用できます。効果。データに非常にランダムにアクセスしている場合、データサイズの選択は重要ではありません-データはページ/キャッシュラインにロードされます。RAMから1バイトだけが必要な場合でも、32バイトを転送できます(これはこれに加えて、CPU/FPUはスーパースカラー(別名パイプライン化)になる可能性があるため、負荷に数サイクルかかる場合がありますが、CPU/FPUはビジー状態になる可能性があります読み込み時間をある程度隠す他の何か(たとえば乗算)。

  5. この規格は、浮動小数点値に特定の形式を強制しません。

仕様がある場合は、それが最適な選択へと導きます。それ以外の場合は、何を使用するかを経験する必要があります。

27
Skizz

Doubleはより正確ですが、8バイトでコーディングされます。 floatは4バイトしかないため、スペースと精度が低くなります。

アプリケーションにdoubleとfloatがある場合、非常に注意する必要があります。過去にそれが原因でバグがありました。コードの一部はfloatを使用し、残りのコードはdoubleを使用していました。 doubleをfloatにコピーしてからfloatをdoubleにコピーすると、精度エラーが発生し、大きな影響を与える可能性があります。私の場合、それは化学工場でした...うまくいけば、劇的な結果はありませんでした:)

アリアン6ロケットが数年前に爆発したのは、この種のバグが原因だと思います!!!

変数に使用される型について慎重に検討する

13
luc

個人的には、ボトルネックが見つかるまで、常に2倍になります。その後、フロートに移動するか、他の部分を最適化することを検討します

6
Eric

これは、コンパイラがdoubleを実装する方法に依存します。 doubleとfloatを同じ型にすることは正当です(一部のシステムではそうです)。

そうは言っても、それらが実際に異なる場合、主な問題は精度です。 doubleは、サイズの違いにより、はるかに高い精度を持ちます。使用している数値が一般的にフロートの値を超える場合は、ダブルを使用します。

他の何人かの人々がパフォーマンスの問題に言及しています。これは、私の考慮​​事項リストの最後です。正しさはあなたの一番の考慮事項でなければなりません。

4
JaredPar

適切な結果を得るために必要な精度を使用 。その後、コードのパフォーマンスが望みどおりになっていない場合(プロファイリングを正しく使用しましたか?)を見てください。

3
user7116

私は、違いに関係なく(誰もが指摘するように、フロートはより少ないスペースを占有し、一般的に高速です)...ダブルを使用してパフォーマンスの問題に苦しむ人はいますか?ダブルを使用すると言います...後で「すごい、これは本当に遅い」と決めたら...パフォーマンスのボトルネックを見つけます(おそらくダブルを使用したという事実ではありません)。それでは、それでもまだ遅すぎる場合は、精度を犠牲にしてフロートを使用できる場所を確認してください。

2
Tom

Floatとdoubleの主な違いは精度です。ウィキペディアには、 単精度 (浮動小数点数)および 倍精度 に関する詳細情報があります。

1

CPUに大きく依存しますが、最も明らかなトレードオフは精度とメモリの間です。 RAMがGBの場合、メモリはあまり問題にならないため、一般的にdoublesを使用する方が適切です。

パフォーマンスに関しては、CPUに大きく依存します。 floatsは通常、32ビットマシンのdoublesよりも優れたパフォーマンスを実現します。 64ビットでは、doublesは(通常)ネイティブサイズであるため、高速になることがあります。それでも、データ型の選択よりも重要なのは、プロセッサでSIMD命令を利用できるかどうかです。

1
Zifre

doubleは精度が高いのに対し、floatはより少ないメモリを使用し、高速です。一般に、十分に正確でない場合を除いて、floatを使用する必要があります。

0
Tal Pressman