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


89

C ++で一方を他方の代わりに使用することの長所と短所は何ですか?


floatの配列とdoubleの配列を作成して、floatのメンバー間に4バイト、doubleのメンバー間に8バイトがあるかどうかを確認した人はいますか?64ビットコンパイラ/コンピュータは、それほど多くを必要としない場合でも、フロート用にメンバーごとに8バイトを予約する可能性があります。
user30156 8219年

回答:


104

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

要するに、その表現のより高い精度double可能にしますが、特定の計算では、より大きなエラーが発生します。「正しい」選択とは、必要な精度を使用し、それ以上使用せず、適切なアルゴリズム選択することです。

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


10
はい。最近のCPUは、ますます大きなメモリチャンク、並列数値処理ユニット、およびパイプラインアーキテクチャをプリフェッチしているため、速度の問題は実際には問題ではありません。大量の数値を処理している場合は、4バイトのfloatと8バイトのdoubleのサイズの違いが、メモリフットプリントに違いをもたらす可能性があります。
ラヴィニオ2009

5
SSE(または任意の頂点浮動小数点ユニット)は、倍精度と比較して、単精度で2倍の数のフロップを処理できます。x87(または任意のスカラー)浮動小数点のみを実行している場合は、おそらく問題にはなりません。
グレッグロジャース

1
@Greg Rogers:現時点では、コンパイラはそれほど賢くありません。生のアセンブリを作成しているのでない限り、大きな違いはありません。そして、はい、これはコンパイラが進化するにつれて変わる可能性があります。
J-16 SDiZ 2009

追記:データがどのように見えるかまったくわからない場合(またはリンク内のすべての計算の手がかりがない場合)は、使用してくださいdouble-ほとんどの場合、より安全です。
J-16 SDiZ 2009

2
この論文は短くはありません。
jokoon 2010

44

特に理由がない限り、doubleを使用してください。

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

典型的な最近のコンピューターでは、doubleはfloatと同じかそれ以上の速さである可能性があるため、大規模な計算であっても、パフォーマンスは通常考慮すべき要素ではありません。(そして、それらは大規模な計算である必要があります。さもないと、パフォーマンスが頭に浮かぶことはありません。私の新しいi7デスクトップコンピューターは、1秒間に60億倍の倍増を実行できます。)


26

質問のコンテキストがないため、この質問に答えることは不可能です。選択に影響を与える可能性のあるものは次のとおりです。

  1. float、double、およびlongdoubleのコンパイラ実装。C ++標準は次のように述べています。

    浮動小数点には、float、double、longdoubleの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. この標準では、浮動小数点値に特定の形式を適用していません。

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


16

Doubleの方が正確ですが、8バイトでコーディングされています。floatはわずか4バイトであるため、スペースと精度が低下します。

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

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

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


3
float / doubleの4/8バイトは保証されていないことに注意してください。これは、プラットフォームによって異なります。それも、同じタイプ...かもしれない
sleske

2
アリアン5のコードは、16ビット符号付き整数にその値が32,767よりも大きかった64ビット浮動小数点を、変換しようとしました。これによりオーバーフロー例外が発生し、ロケットが自己破壊シーケンスを開始しました。問題のコードは、古くて小さいロケットから再利用されたコードでした。
cmwt

5

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


4

これは、コンパイラがdoubleを実装する方法によって異なります。doubleとfloatが同じタイプであることは合法です(そしてそれはいくつかのシステムにあります)。

そうは言っても、それらが実際に異なる場合、主な問題は精度です。ダブルはサイズの違いにより、はるかに高い精度を持っています。使用している数値が通常floatの値を超える場合は、doubleを使用してください。

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



2

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



1

これはCPUに大きく依存しますが、最も明らかなトレードオフは精度とメモリの間です。GBのRAMでは、メモリはそれほど問題にならないため、通常はdoublesを使用することをお勧めします。

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


0

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


5
典型的な最近のコンピューターでは、doubleはfloatと同じくらい高速です。
トーマスパドロン-マッカーシー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.