例:
float timeRemaining = 0.58f;
f
この番号の最後にが必要なのはなぜですか?
フロートの宣言には、次の2つの部分が含まれます。
timeRemaining
変数が型であることを宣言しますfloat
。0.58
この変数に値を割り当てます。問題はパート2で発生します。
右側はそれ自体で評価されます。C#仕様によれば、接尾辞のない小数点を含む数値は、として解釈されますdouble
。
これでdouble
、型の変数に割り当てる値ができましたfloat
。これを行うには、からdouble
への暗黙の変換が必要float
です。変換中に情報が失われる可能性があるため(この場合はそうなります)、そのような変換はありません。
その理由は、コンパイラが使用する値が実際には0.58ではなく、0.58に最も近い浮動小数点値である0.57999999999999978655962351581366 ...の場合、double
および正確に0.579999946057796478271484375の場合ですfloat
。
厳密に言えば、は必須でf
はありません。値を:f
にキャストすることで、サフィックスを使用する必要をなくすことができます。float
float timeRemaining = (float)0.58;
0.58
コンパイラが値:float
、、double
およびを表すために使用できる数値タイプがいくつかあるためdecimal
です。コンパイラーが1つを選択することに問題がない限り、曖昧さを解消する必要があります。
のドキュメントに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
オペランドを含むすべてのシナリオで何が起こるかを明示的に指定するか、タイプ間の暗黙的な変換を1つで実行できるようにする必要があることです。方向のみ。Microsoftは、Javaの先導に従うことを選択して、精度を優先する場合もありますが、正確さを犠牲にすることが多く、一般的に面倒な方向性を示しています。
ほとんどすべての場合、double
特定の数値に最も近い値を取得し、それをaに割り当てると、同じ量に最も近い値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つの表現のいずれかが得られます。
この望ましい動作は、極端な場合でも適用されることに注意してください。たとえば、float
数量10 ^ 308の最良の表現は、その量float
の最良の表現を変換することによって達成される表現と一致しdouble
ます。同様に、float
10 ^ 309の最良の表現は、その量float
の最良の表現を変換することによって達成される表現と一致します。double
残念ながら、明示的なキャストを必要としない方向への変換は、それほど正確ではありません。float
値の最良の表現をに変換しても、その値double
の最良の表現に特に近いものが得られることはめったになくdouble
、場合によっては、結果が数百桁ずれることもあります(たとえばfloat
、10 ^ 40の最良の表現をに変換するdouble
と、double
10^300の最良の表現よりも大きい値を比較する値。
残念ながら、変換ルールはそのままであるため、「安全な」方向に値を変換するときは、ばかげたタイプキャストとサフィックスを使用する必要があります。また、危険な方向に暗黙のタイプキャストを行うと、偽の結果が頻繁に発生することに注意する必要があります。