著者が使用しているのを見た多くの場所があります。
sprite.anchorPoint = CGPointMake(1, 0.5f);
つまり、0.5
代わりに使用しないのはなぜですか0.5f
-- を使用する利点はあり0.5f
ますか?
著者が使用しているのを見た多くの場所があります。
sprite.anchorPoint = CGPointMake(1, 0.5f);
つまり、0.5
代わりに使用しないのはなぜですか0.5f
-- を使用する利点はあり0.5f
ますか?
0.5
はdouble
定数です0.5f
が、 はfloat
定数です。
0.5f を使用する利点はありますか?
はい。計算の型 (読み取り: 精度) を指定するか、暗黙的な縮小 (および関連するコンパイラの警告) を回避する必要があります。
あなたが提供する例は、コンパイラの警告を回避したり、パラメーターの型に関して非常に厳密であることを超えて、説得力がありません。
ただし、倍精度への明白ではない昇格はコストがかかる可能性があります。
「0.5f と 0.5 のどちらを使うべきか」の答え: それぞれに適切なタイミングがあるため、プログラムでは両方を使用する必要があります。必要な計算/精度に適した型、渡すパラメーターの型、または式の他の値に適した型のいずれかを使用する必要があります。これはちょうど整数のようなものです -- 幅を考慮するのに適切な時期があり、接尾辞を付けるのに適切な時期があります (例えばU
and L
)。区別が重要な場合もあれば、(当然のことながら)重要でない場合もあります。
定数 0.5 は、Objective-C で double を宣言し、末尾に f を付けます。0.5f は、定数を (32 ビット) float として宣言します。Objective-C/C の投稿で number/float の後
の "f" を見てください。
double 定数が適切な場合に float 定数を使用すると、次のような結果が生じます。
多くの定数は値を変更します。たとえば、.3 は .3f と等しくありません。ソース テキストに 10 進数が含まれている場合、コンパイラはそれを浮動小数点で表現可能な値に変換する必要があります。1999 C 標準では、表現可能な最も近い値または表現可能な最も近い値に変換する必要があります。優れたコンパイラは、どちらの方向でも最も近い値に変換し、同点の場合は最下位ビットがゼロの値を選択します。(このような値を返すことを「正しい丸め」と呼びます。) 一般的に使用されている浮動小数点形式に正しく丸めると、.3 は 0x1.3333333333333p-2 になり、.3f は 0x1.333334p-2 になります。(これらは 16 進浮動小数点定数です。「0x」の後ろと「p」の前の部分は 16 進数で、「p」の後の部分は 2 の 10 進指数です。つまり、0x3.cp4 は 0x3.c に 2 を掛けたものです。4、つまり (3 + 12/16)⋅2 4 = 60.)
式はタイプを変更します。算術演算子のオペランドに float オペランドと double オペランドの両方が含まれている場合、float オペランドは double に変換されます。これにより、計算値が変化する可能性があります。1999 C 標準では、コンパイラが浮動小数点値をその型が必要とするよりも高い精度と範囲で表すことを許可しているため、浮動小数点値は double レジスタに保持され、double 演算で操作される可能性があります。ただし、double 定数を使用する場合は、コンパイラで double 演算を使用する必要があります。したがって、float x に 0x1.24924ap-3 (約 1/7) が含まれる場合、「x + .5f」は 0x1.492492p-1 を生成する可能性があり、「x + .5」は 0x1.4924928p-1 を生成する必要があります。
Objective C、C++、および引数の型に基づいて呼び出す関数を選択できるその他の言語では、引数の型を変更すると、実行されるコードが完全に変更される可能性があります。呼び出し「foo(.5f)」は、「foo(.5)」がネットワーク ソケットに書き込む間にメモリを割り当てるルーチンを呼び出すことができます。これは通常、呼び出されるオブジェクトの設計としては不適切ですが、オブジェクトが引数の型に敏感でなければならない特別な状況があります。また、これは (tgmath.h のように) C では技術的に可能ですが、まれです (通常、プリプロセッサを使用して、引数のサイズをテストする式になるように「foo」を定義する必要があります)。
上記のリストは、すべてを網羅することを意図したものではありません。
一方、コードやデータのサイズが問題になることはめったにありません。.5f と .5 のどちらを記述しても、コンパイラが実際に float または double を格納するという保証はありません。たとえば、「printf("%g", 3.*4.+5.)」と書いた場合、コンパイラは 3、4、または 5 を格納する必要はありません。これは、3、4、および 5 を保存して実行時に計算するか、17 を保存して実行時に printf に渡すか、文字列「17」のみを保存してそれを数値を格納したり、printf を呼び出したりすることはありません。
したがって、通常、どのタイプを使用するかについて重要なことは、実行したい計算を適切に表現し、最適化について心配しないことです。「foo(.5)」と記述し、foo に double パラメーターがある場合、コンパイラーはプログラムの定数に .5f を格納し、実行時に .5f を double レジスターにロードして foo に渡すコードを生成する場合があります。 . 優れたコンパイラは、追加の実行コストなしでロードできる最小の形式で定数を格納することを期待しています。
浮動小数点定数はデフォルトでsであるため、末尾f
は定数を強制的に単精度にします。これは、いくつかのコンパイラのリビジョンよりも前により重要でした。なぜなら、コンパイラはそうすることによる副作用がないことを保証できなかったため、double から float への自動型変換があったとは思わないからです。その結果、多くのコードが指定子を保持して、単精度浮動小数点レジスタのみが必要な場合に倍精度浮動小数点レジスタをロードする際のサイクルの書き込みを回避することになりました。float
double
f
また、0.5は単精度浮動小数点と倍精度浮動小数点の両方で正確に表現できることを考慮したいと思います。これは、それらがまったく同じであることを意味します。値0.5は仮数の単一ビット(暗黙ビット)のみを必要とし、残りのすべてのビットは0であるため、それぞれの形式で使用可能な有効ビットの数は重要ではありません。
したがって、ストレージスペースを節約する必要がある場合は、0.5fが推奨されます。