例:
float timeRemaining = 0.58f;
数字の最後にf
が必要なのはなぜですか?
フロートの宣言には2つの部分が含まれます。
timeRemaining
がfloat
型であることを宣言します。0.58
をこの変数に割り当てます。この問題はパート2で発生します。
右側はそれ自体で評価されます。 C#仕様によると、サフィックスのない小数点を含む数値はdouble
として解釈されます。
これで、double
型の変数に割り当てるfloat
値ができました。これを行うには、double
からfloat
への暗黙的な変換が必要です。このような変換はありません。変換中に情報が失われる可能性があるためです(この場合は失われます)。
コンパイラが使用する値は実際には0.58ではなく、0.58に最も近い浮動小数点値であり、double
の場合は0.57999999999999978655962351581366 ...であり、float
の場合は正確に0.579999946057796478271484375です。
厳密に言えば、f
は必要ありません。値をf
にキャストすることで、float
サフィックスを使用する必要がなくなります。
float timeRemaining = (float)0.58;
コンパイラが値0.58
を表すために使用できるいくつかの数値型があるため、: float
、 double
および- decimal
。コンパイラが選択してくれるのでなければ、明確にする必要があります。
double
のドキュメントでは、自分で型を指定しない場合、コンパイラは常に実際の数値リテラルの型としてdouble
を選択すると述べています。
デフォルトでは、代入演算子の右側にある実数値リテラルはdoubleとして扱われます。ただし、整数をdoubleとして処理する場合は、サフィックスdまたはDを使用します。
サフィックスf
を追加すると、float
が作成されます。接尾辞d
はdouble
を作成します。サフィックスm
はdecimal
を作成します。これらはすべて大文字でも機能します。
ただし、これでコンパイルできない理由を説明するにはまだ不十分です。
float timeRemaining = 0.58;
答えの欠けている半分は、double
0.58
からfloat
timeRemaining
への変換が潜在的に情報を失うため、コンパイラは暗黙的にそれを適用することを拒否するということです。明示的なキャストを追加すると、変換が実行されます。 f
サフィックスを追加する場合、変換は必要ありません。どちらの場合も、コードはコンパイルされます。
問題は、.NETが、float
およびdouble
を含むいくつかのタイプの暗黙的な操作を実行できるようにするために、混合オペランドを含むすべてのシナリオで何が起こるかを明示的に指定するか、そうでない場合は、型間の暗黙的な変換を一方向のみで実行できます。 MicrosoftはJavaのリードに従うことを選択しました。これは、精度をときどき好む方向を可能にしますが、しばしば正確さを犠牲にし、通常は面倒を生じさせます。
ほとんどすべての場合、特定の数値に最も近いdouble
値を取得してfloat
に割り当てると、その同じ量に最も近いfloat
値が得られます。値9,007,199,791,611,905など、いくつかのコーナーケースがあります。最適なfloat
表現は9,007,200,328,482,816(536,870,911でオフ)になりますが、最高のdouble
表現(つまり9,007,199,791,611,904)をfloat
にキャストすると9,007,199,254,740,992(536,870,913オフ)になります)。ただし、一般的に、ある量の最高のdouble
表現をfloat
に変換すると、可能な限り最高のfloat
表現、または本質的に同等の2つの表現のいずれかが得られます。
この望ましい動作は、極端な場合でも適用されることに注意してください。たとえば、数量10 ^ 308の最適なfloat
表現は、その数量の最適なfloat
表現を変換することによって達成されるdouble
表現と一致します。同様に、10 ^ 309の最高のfloat
表現は、その量の最高のfloat
表現を変換することによって達成されるdouble
表現と一致します。
残念ながら、明示的なキャストを必要としない方向への変換は、ほとんど正確ではありません。値の最適なfloat
表現をdouble
に変換すると、その値の最適なdouble
表現に特に近いものはほとんど得られず、場合によっては結果がオフになります。数百桁(たとえば、10 ^ 40の最高のfloat
表現をdouble
に変換すると、10 ^ 300の最高のdouble
表現よりも大きい値が得られます。
悲しいかな、変換ルールはそのままなので、値を「安全な」方向に変換する際に愚かな型キャストと接尾辞を使用しなければなりません。また、しばしば誤った結果をもたらす危険な方向の暗黙の型キャストに注意してください。