floatからdoubleへの変換
-
07-07-2019 - |
質問
float
から double
への変換はどれくらい高価ですか? int
から long
への変換と同じくらい簡単ですか?
編集:floatが4バイト、doubleが8バイトのプラットフォームを想定しています
解決
プラットフォームに関する考慮事項
これは、浮動小数点計算に使用されるプラットフォームに依存します。 x87 FPUでは、レジスターの内容が同じであるため、変換は無料です-時々支払うかもしれない唯一の価格はメモリトラフィックですが、多くの場合、変換なしで値を使用できるため、トラフィックもありません。 x87は実際にはこの点で奇妙な獣です-使用される命令とレジスタが同じであるため、浮動小数点と倍精度浮動小数点を適切に区別するのは困難です。異なるのはロード/ストア命令であり、計算精度自体はステータスビットを使用して制御されます。 float / doubleの混合計算を使用すると、予期しない結果になる可能性があります(このため、正確な動作と最適化戦略を制御するコンパイラーコマンドラインオプションがあります)。
SSEを使用する場合(および場合によってはVisual StudioがデフォルトでSSEを使用する場合)、FPUレジスタ内の値を転送するか、変換を実行するために明示的に何かを行う必要があるため、異なる場合があります。
メモリ節約パフォーマンス
要約として、および他の場所でのコメントへの回答:浮動小数点計算の結果を32bストレージに保存する場合、結果は同じ速度または高速になります。理由は次のとおりです。
- x87でこれを行う場合、変換は無料です-唯一の違いはfstp qword []の代わりにfstp dword []が使用されることです。
- SSEを有効にしてこれを行うと、計算の精度がデフォルトのdoubleのfloat insteeadになったときにSSEで一部のfloat計算を実行できるため、パフォーマンスが向上する場合があります。
- すべての場合で、メモリトラフィックが少なくなります
他のヒント
一部のプラットフォームでは浮動小数点から倍精度への変換が無料で発生します(PPC、x86コンパイラー/ランタイムが使用するように指示したタイプの" to hellを使用する場合、とにかくlong doubleですべてを評価します、nyah nyah"評価モード)。
浮動小数点の評価が実際にSSEレジスタを使用して指定された型で行われるx86環境では、floatとdouble間の変換は浮動小数点の加算または乗算とほぼ同じくらい高価です(つまり、あなたはそれらの多くを しています。
ハードウェア浮動小数点のない組み込み環境では、多少コストがかかります。
これは、使用しているC ++実装に固有のものです。 C ++では、デフォルトの浮動小数点型は double です。コンパイラは、次のコードに対して警告を発行する必要があります。
float a = 3.45;
double値3.45がfloatに割り当てられているため。特にfloatを使用する必要がある場合は、値の末尾に f :
を付けます。float a = 3.45f;
ポイントは、すべての浮動小数点数はデフォルトで double です。コンパイラの実装の詳細がわからず、浮動小数点計算について十分に理解していない場合は、このデフォルトのままにしておくと安全です。キャストを避けます。
C ++プログラミング言語のセクション4.5も参照してください。
もっと複雑になるとは想像できません。 intからlongへの変換とfloatからdoubleへの変換の大きな違いは、int型には2つのコンポーネント(符号と値)があり、浮動小数点数には3つのコンポーネント(符号、仮数、指数)があることです。
IEEE 754単精度がエンコードされます 符号に1ビットを使用する32ビット、8 指数のビット、および23ビット 仮数。ただし、 隠れビットなので、仮数は24です ビット(p = 24)、たとえ 23ビットのみを使用してエンコードされます。
-David Goldberg、すべてのコンピューター科学者が浮動小数点について知っておくべきこと算術演算
したがって、floatとdoubleの間の変換は同じ符号ビットを保持し、floatの仮数の最後の23/24ビットをdoubleの仮数に設定し、floatの指数の最後の8ビットをdoubleの指数に設定します。
この動作は、 IEEE 754 によっても保証されている可能性があります。それをチェックしたので、私にはわかりません。
おそらく、必要なメモリが大きくなり、操作がより複雑になるため、intをlongに変換するよりも少し遅くなります。 メモリアライメントの問題
たぶんこのヘルプ:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
double _ftod(float fValue)
{
char czDummy[30];
printf(czDummy,"%9.5f",fValue);
double dValue = strtod(czDummy,NULL);
return dValue;
}
int main(int argc, char* argv[])
{
float fValue(250.84f);
double dValue = _ftod(fValue);//good conversion
double dValue2 = fValue;//wrong conversion
printf("%f\n",dValue);//250.840000
printf("%f\n",dValue2);//250.839996
getch();
return 0;
}