c#の「int」にキャストするときに 'float'とは異なる 'const float'値
-
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#言語仕様:
定数式のコンパイル時評価は、実行時評価が例外をスローした場合に、コンパイル時評価がコンパイル時のエラーを引き起こすことを除いて、定数式以外の式と同じ規則を使用します。発生します。
しかし、我々が上記で観察すると、実際にはより高精度を使用することができ、そしてこの強化された精度が実際には直接制御の下にはない。
と明らかに、さまざまな状況では、結果はあなたが観察したものの反対方向である可能性があります - コンパイラはより低い精度に落下し、ランタイムは代わりに高精度を維持することができました。
他のヒント
これはここでは重複する質問であるとは言えない - >
intのintとconst intに関して非常に似たものを説明しました。
主なアイデアは、コードを生成する前にコンパイラによって計算された2つの定数の分割が実行時にではなく、この特定の場合では、この特定の場合では double フォーマット。したがって、XScalesizecは基本的に34.9999に等しいです。そのため、実行時にキャストが実行されると34。