c#の「int」にキャストするときに 'float'とは異なる 'const float'値

StackOverflow https://stackoverflow.com//questions/24016294

  •  21-12-2019
  •  | 
  •  

質問

あなたのいずれかを説明することはなぜこれが起こるのか?

static void Main()
{
    const float xScaleStart = 0.5f;
    const float xScaleStop = 4.0f;
    const float xScaleInterval = 0.1f;
    const float xScaleAmplitude = xScaleStop - xScaleStart;

    const float xScaleSizeC = xScaleAmplitude / xScaleInterval;

    float xScaleSize = xScaleAmplitude / xScaleInterval;

    Console.WriteLine(">const float {0}, (int){1}", xScaleSizeC, (int)xScaleSizeC);

    Console.WriteLine(">      float {0}, (int){1}", xScaleSize, (int)xScaleSize);

    Console.ReadLine();
}
.

出力:

>const float 35, (int)34
>      float 35, (int)35
.

0.1のバイナリ表現は実際には0.099999990463256835937であることを知っていますが、なぜ 'const float'を使用して 'float'を使用しても起こりませんか?これはコンパイラのバグと見なされますか?

レコードの場合、コードは次のようにコンパイルされます。

private static void Main(string[] args)
{
    float xScaleSize = 35f;
    Console.WriteLine(">const float {0}, (int){1}", 35f, 34);
    Console.WriteLine(">      float {0}, (int){1}", xScaleSize, (int)xScaleSize);
    Console.ReadLine();
}
.

役に立ちましたか?

解決

これの「なぜ」は基本的に頻繁に沸騰することになります。これは、仮想実行システム(VES)仕様( Partition I ):

浮動小数点数は内部浮動小数点を使用して表されます。 タイプ。そのような各インスタンスでは、変数または式の公称タイプは、floatまたはfloatですが、 値は追加の範囲および/または精度で内部的に表すことができます

それから後で私たちは:

doubleまたはfloat32よりも広い内部表現の使用は、違いを引き起こす可能性があります。 開発者が自分のコードに一見無関係の変更を加えるときの計算結果、その結果 これは、値が内部表現(例えば、登録内)からの位置にこぼれている可能性があります。 スタック。

今、 C#言語仕様

定数式のコンパイル時評価は、実行時評価が例外をスローした場合に、コンパイル時評価がコンパイル時のエラーを引き起こすことを除いて、定数式以外の式と同じ規則を使用します。発生します。

しかし、我々が上記で観察すると、実際にはより高精度を使用することができ、そしてこの強化された精度が実際には直接制御の下にはない。


と明らかに、さまざまな状況では、結果はあなたが観察したものの反対方向である可能性があります - コンパイラはより低い精度に落下し、ランタイムは代わりに高精度を維持することができました。

他のヒント

これはここでは重複する質問であるとは言えない - > Eric Postpischilコメント

intのintとconst intに関して非常に似たものを説明しました。

主なアイデアは、コードを生成する前にコンパイラによって計算された2つの定数の分割が実行時にではなく、この特定の場合では、この特定の場合では double フォーマット。したがって、XScalesizecは基本的に34.9999に等しいです。そのため、実行時にキャストが実行されると34。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top