ここでOGRE3d について読んでいるチュートリアルでは、プログラマーは初期化f
する変数の最後に常に追加しています。変数の終わり?200.00f
0.00f
f
f
編集:つまり、変数を200.03
初期化しても浮動小数点として初期化されないと言っているのですが、そうするとそう200.03f
なるでしょうか? そうでない場合、 f はどこで役に立ちますか?
これは、数値を "double" ではなく "float" として解釈する必要があることを指定する方法です (これは C++ 10 進数の標準であり、2 倍のメモリを使用します)。
この議論は役に立つかもしれません:
http://msdn.microsoft.com/en-us/library/w9bk1wcy.aspxから引用
f、F、l、または L サフィックスのない浮動小数点定数の型は double です。文字 f または F がサフィックスの場合、定数の型は float です。文字 l または L を接尾辞として付けると、long double 型になります。例えば:
200.00f
変数ではありません。変化することはありません。
float
これは、表現を伴うコンパイル時の定数です。は、f
であることを示しますfloat
。
比較すると、200.00
として解釈されますdouble
。
C 標準では、定数 float は double であり、操作が double に昇格されると規定されています。
float a,b,c;
...
a = b+7.1; this is a double precision operation
...
a = b+7.1f; this is a single precision operation
...
c = 7.1; //double
a = b + c; //single all the way
倍精度では、定数用により多くのストレージが必要であり、さらに変数オペランド用に単精度から倍精度への変換が必要です。次に、結果を代入するために倍精度から単精度への変換が必要です。浮動小数点の動作方法に慣れていない場合、すべての変換が行われるため、丸めなどを行うと、得ようとしていると思っていた結果が得られない可能性があります。コンパイラーは、パスのある時点でこの動作の一部を最適化して、実際の問題を理解するのを難しくし、ハードウェアの fpu が混合モードのオペランドを受け入れ、実際に何が起こっているのかを隠す可能性があります。
速度の問題だけでなく、精度の問題もあります。最近 SO の質問がありましたが、ほとんど同じ問題です。なぜこの比較はある数値で機能し、別の数値では機能しないのですか。たとえば、0.454545 のように 5/11 の分数を取ります....仮に、有効桁数 3 桁の単精度と有効桁数 6 桁の倍精度を持つ基数 10 fpu があるとします。
float a = 0.45454545454;
...
if(a>0.4545454545) b=1;
...
私たちの仮想システムでは、a に 3 桁しか格納できないため、a = .455 です。これは、デフォルトで切り上げ丸めモードを使用しているためです。ただし、数値の末尾に f を付けていないため、比較は 2 倍と見なされます。double バージョンは 0.454545 です。a は double に変換され、結果は 0.455000 になるため、次のようになります。
if(0.455000>0.454545) b = 1;
0.455 は 0.454545 より大きいので、b は 1 になります。
float a = 0.45454545454;
...
if(a>0.4545454545f) b=1;
...
したがって、比較は単精度であるため、0.455 と 0.455 を比較していますが、これは大きくないため、b=1 は発生しません。
基数 10 の浮動小数点定数を記述する場合、コンピューターの浮動小数点数は基数 2 であり、基数 11 では 5/11 が正常に機能するように常にスムーズに変換されるとは限りませんが、基数 10 では無限の繰り返し数字が得られます。 . たとえば、10 進数で 0.1 を指定すると、2 進数で繰り返しパターンが作成されます。仮数が切り捨てられる場所に応じて、丸めによって仮数の lsbit が切り上げられるかどうかが決まります (使用している浮動小数点形式に丸めがある場合は、使用している丸めモードにも依存します)。上記の比較が示すように、変数の使用方法に応じて、どちらが問題を引き起こしますか。
非浮動小数点の場合、コンパイラは通常あなたを救いますが、そうでない場合もあります:
unsigned long long a;
...
a = ~3;
a = ~(3ULL);
...
コンパイラとコンピューターによっては、2 つの割り当てによって異なる結果が得られる可能性があります。
特定の何かが必要な場合は、必要なものをコンパイラーに伝えるときに明確にする必要があります。そうしないと、コンパイラーは推測を行い、常に必要な推測を行うとは限りません。
これは、値が単精度浮動小数点変数 (type float
) として解釈されることを意味します。f サフィックスがない場合、倍精度浮動小数点変数 (タイプdouble
) として解釈されます。
これは通常、 float 変数に double 値を代入することによって精度が失われる可能性に関するコンパイラの警告を黙らせるために行われます。このような警告を受け取らなかった場合は、コンパイラの設定で警告を無効にしている可能性があります (これは悪いことです!)。
しかし、微妙な構文上の意味を持つこともあります。ご存じのとおり、C++ では、名前は同じでもパラメーターの型が異なる関数を使用できます。その場合、f サフィックスによって、どの関数が呼び出されるかが決まります。