C ++で一方を他方の代わりに使用することの利点と欠点は何ですか?
11 に答える
特別な理由がない限り、double を使用してください。
おそらく驚くべきことに、C (および C++) の「通常の」浮動小数点型は double であり、float ではありません。sinやlogなどの標準の数学関数は double を引数として取り、double を返します。プログラムで3.14を記述する場合のように、通常の浮動小数点リテラルの型は double です。浮きません。
典型的な最新のコンピューターでは、double は float と同じかそれ以上の速度になる可能性があるため、通常、大規模な計算であっても、パフォーマンスは考慮すべき要素ではありません。(そして、それらは大規模な計算である必要があり、さもないとパフォーマンスが頭に浮かびません。私の新しい i7 デスクトップ コンピューターは、1 秒間に 60 億回の double の乗算を実行できます。)
質問の文脈がないため、この質問に答えることは不可能です。選択に影響を与える可能性のあるものは次のとおりです。
float、double、およびlongdoubleのコンパイラ実装。C++標準は次のように述べています。
浮動小数点のタイプには、float、double、およびlongdoubleの3つがあります。型doubleは、少なくともfloatと同じ精度を提供し、型long doubleは、少なくともdoubleと同じ精度を提供します。
したがって、3つすべてをメモリ内で同じサイズにすることができます。
FPUの存在。すべてのCPUにFPUがあるわけではなく、浮動小数点タイプがエミュレートされることもあれば、浮動小数点タイプがサポートされないこともあります。
FPUアーキテクチャ。IA32のFPUは内部で80ビットです-32ビットと64ビットのフロートはロード時に80ビットに拡張され、ストアで削減されます。4つの32ビットフロートまたは2つの64ビットフロートを並列に実行できるSIMDもあります。SIMDの使用は標準で定義されていないため、SIMDを使用できるかどうかを判断するために、より複雑な分析を行うコンパイラが必要になるか、特別な関数(ライブラリまたは組み込み関数)を使用する必要があります。80ビット内部フォーマットの結果は、データがRAMに保存される頻度に応じて、わずかに異なる結果が得られる可能性があることです(したがって、精度が低下します)。このため、コンパイラは浮動小数点コードを特に適切に最適化しません。
メモリ帯域幅。doubleがfloatよりも多くのストレージを必要とする場合、データの読み取りに時間がかかります。それは素朴な答えです。最新のIA32では、データの出所によって異なります。L1キャッシュにある場合、データが単一のキャッシュラインからのものであれば、負荷はごくわずかです。複数のキャッシュラインにまたがる場合は、わずかなオーバーヘッドが発生します。L2からの場合は時間がかかり、RAMにある場合はさらに長くなり、最後にディスク上にある場合は非常に時間がかかります。したがって、floatまたはdoubleの選択は、データの使用方法ほど重要ではありません。大量のシーケンシャルデータに対して小さな計算を実行する場合は、小さなデータ型をお勧めします。小さなデータセットで多くの計算を行うと、大きなデータ型を使用して大きな効果を得ることができます。もし、あんたが' 非常にランダムにデータに再アクセスする場合、データサイズの選択は重要ではありません。データはページ/キャッシュラインにロードされます。したがって、RAMから1バイトだけが必要な場合でも、32バイトを転送することができます(これはシステムのアーキテクチャに大きく依存します)。これらすべてに加えて、CPU / FPUはスーパースカラー(別名パイプライン)である可能性があります。したがって、ロードには数サイクルかかる場合がありますが、CPU / FPUは、ロード時間をある程度隠す他の何か(たとえば乗算)を実行するのに忙しい可能性があります。
この標準では、浮動小数点値に特定の形式は適用されません。
仕様がある場合は、それが最適な選択につながります。それ以外の場合は、何を使用するかを経験する必要があります。
Double の方が正確ですが、8 バイトでコード化されます。float はわずか 4 バイトであるため、スペースが少なく、精度が低くなります。
アプリケーションに double と float がある場合は、十分に注意する必要があります。過去にそれが原因でバグがありました。コードの一部は float を使用し、残りのコードは double を使用していました。double を float にコピーしてから float を double にコピーすると、大きな影響を与える精度エラーが発生する可能性があります。私の場合、それは化学工場でした...うまくいけば、劇的な結果はありませんでした:)
数年前にアリアン6ロケットが爆発したのは、このようなバグのせいだと思います!!!
変数に使用する型を慎重に検討する
CPU に大きく依存しますが、最も明白なトレードオフは精度とメモリの間です。GB の RAM では、メモリはそれほど問題にならないため、通常はdouble
s を使用することをお勧めします。
パフォーマンスに関しては、CPU に大きく依存します。float
s は通常double
、32 ビット マシンの s よりも優れたパフォーマンスを発揮します。64 ビットでdouble
は、(通常) ネイティブ サイズであるため、s の方が速い場合があります。それでも、データ型の選択よりもはるかに重要なのは、プロセッサで SIMD 命令を利用できるかどうかです。
double の方が精度が高いのに対し、float は使用するメモリが少なく、高速です。一般に、精度が十分でない場合を除き、float を使用する必要があります。