92

例:

float timeRemaining = 0.58f;

fこの番号の最後にが必要なのはなぜですか?

4

3 に答える 3

101

フロートの宣言には、次の2つの部分が含まれます。

  1. timeRemaining変数が型であることを宣言しますfloat
  2. 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;
于 2012-07-21T07:29:50.457 に答える
38

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変換は必要ありません。どちらの場合も、コードはコンパイルされます。

于 2012-07-17T09:35:37.147 に答える
3

問題は、.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ます。同様に、float10 ^ 309の最良の表現は、その量floatの最良の表現を変換することによって達成される表現と一致します。double

残念ながら、明示的なキャストを必要としない方向への変換は、それほど正確ではありません。float値の最良の表現をに変換しても、その値doubleの最良の表現に特に近いものが得られることはめったになくdouble、場合によっては、結果が数百桁ずれることもあります(たとえばfloat、10 ^ 40の最良の表現をに変換するdoubleと、double10^300の最良の表現よりも大きい値を比較する値。

残念ながら、変換ルールはそのままであるため、「安全な」方向に値を変換するときは、ばかげたタイプキャストとサフィックスを使用する必要があります。また、危険な方向に暗黙のタイプキャストを行うと、偽の結果が頻繁に発生することに注意する必要があります。

于 2013-06-21T23:37:02.450 に答える