- ベストアンサー
浮動小数点の定数
基本的なことで恐縮ですが、 float f = 1; float f = 1.f; および double d = 1; double d = 1.0; これらは、違いがあるのでしょうか。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
押さえておくべきことは、以下の点です。 ・小数点を含んだ定数の型は double (float ではない) ・小数点を含んでいない定数の型は int ・float と double の演算は、一度 double に拡張されてから行われる。 この意味で、 float f = 1; は、int の 1 を最終的に float に変換して代入しています。 float f = 1.f; は、float の 1 を代入しています。 double d = 1; は、 int の 1 を double に変換して代入しています。 double d = 1.0; は、double の 1 を代入しています。 いずれにしても、 ・単純な代入 ・結果として、整数値になる場合 は、実害はありません。(比較を含めて)演算を行うときに問題が見えてきます。 たとえば、 float f = 0.1; if ( f == 0.1) という比較は、失敗します。 これは、0.1 という double の値(これは、2進数展開したら、無限小数になります)と、float の 0.1 を double に拡張したものは、別の値になるからです。 説明のために、10進数で考えます。 float が、10進 3桁。 double が 10進6桁と仮定します。また、無限小数にするために、0.33333... を考えましょう。 float f = 0.3333333333; で fに代入されるのは、この例では、 0.333 です。 ここで、 f == 0.3333333333333; の比較は、「一度 double の制度に合わされる」のですが、f は、float なので、0.333 を double に拡張して、 0.333000 になります。 一方、0.33333333333333 は、double 値として、(例では)6桁の精度を持ちますから、 0.333333 です。 つまり、0.333000 と 0.333333 を比較することになり、この比較は失敗します。 ここで、 float f = 0.1f; if (f == 0.1f) であれば、同じ精度で比較されるので、この比較は、成功します。 他にも、float の f に対して、 f * 0.1; などとするのと、 f * 0.1f などとするのでは、前者が一度 doubleに変換されるため、結果が一致しない可能性があります。 また、単純な代入ではなく、 int x = 1; double y = x / 3; と double y = x / 3.; では、結果が異なります。 前者は、「小数点がない定数の型は int 」なので、int / int の計算がされて、一度、0となります。 これが、double に変換されて、y に代入されるので、 y は、0になります。 後者では、「小数点のある定数の型は double」なので、x / 3. は、int / double と見なされます。 この場合、割り算の前に、x が double に変換されて、double / double の計算が行われます。 この結果、x / 3. は、0.3333... という結果を持ちます。 故に、y の値は、 0.3333... になります。 こういう点は、注意すべき点です。
その他の回答 (2)
- jacta
- ベストアンサー率26% (845/3158)
質問にだけ答えます。 > float f = 1; > float f = 1.f; > の違いだけでも、よいのかもしれません。 > 1.fと記述する'f'について知りたいのです。 末尾の f は、その浮動小数点定数がfloat型であることを意味しています。既に回答が出ているように、単なる 1 の場合には、いったんfloat型に型変換されてからオブジェクト f を初期化します。それに対して 1.f の場合は、もともとfloat型ですので型変換の必要性はありません。 どちらの場合もコンパイルされてしまえば(体感できないほどのコンパイル時間の微小な差を除けば)同じです。ただし、インタプリタでは実行時に型変換が行われることになるでしょうから、内部的な動作が異なる可能性はあります(見かけ上の動作は変わりません)。
- jacta
- ベストアンサー率26% (845/3158)
どれとどれの違いですか?(質問文からは複数の意味に取れます) また、どういった観点からの違いですか?
補足
説明が足らずに済みません。 float f = 1; float f = 1.f; の違いだけでも、よいのかもしれません。 1.fと記述する'f'について知りたいのです。
お礼
大変に役に立ちました。 丁寧な説明をいただきありがとうございます。