14
        string[] strArray = new string[10] { "21.65", "30.90", "20.42", "10.00", "14.87", "72.19", "36.00", "45.11", "18.66", "22.22" };
        float temp = 0.0f;
        Int32 resConvert = 0;
        Int32 resCast = 0;
        for (int i = 0; i < strArray.Length; i++)
        {
            float.TryParse(strArray[i], out temp);
            resConvert = Convert.ToInt32(temp * 100);
            resCast = (Int32)(temp * 100);
            Console.WriteLine("Convert: " + resConvert + " ExplCast: " + resCast);
        }

答え:

   Convert: 2165 ExplCast: 2164   // ??
   Convert: 3090 ExplCast: 3089   // ??
   Convert: 2042 ExplCast: 2042
   Convert: 1000 ExplCast: 1000
   Convert: 1487 ExplCast: 1486   //??
   Convert: 7219 ExplCast: 7219
   Convert: 3600 ExplCast: 3600
   Convert: 4511 ExplCast: 4511
   Convert: 1866 ExplCast: 1865   //??
   Convert: 2222 ExplCast: 2221   //??

Explicit Cast を実行しているときに値が異なることがありますが、常にではありません。何らかの理由 ?

4

5 に答える 5

9

一例を挙げると、21.65float形式は実際には 21.6499999 のような数値で表されます。は数値を最もConvert.ToInt32近い整数に丸め、21.65 を生成しますが、明示的なキャストは単純に(Int32)切り捨てる (ゼロに向かって丸める) ため、21.64 になります。

浮動小数点数を、印刷されたものと同じようにコンピューターで表現したい場合は、またはdecimalの代わりに を使用します。floatdouble

于 2012-06-29T12:25:06.033 に答える
4

Convert.ToInt32 最も近い整数に丸められますが、直接キャストでは数値が切り捨てられます。

したがって、浮動小数点の不正確さのために の2165.99999whatever代わりに の値を持っている場合2165.0、直接キャストは浮動小数点の後のすべてを切り捨てConvert.ToInt32、最も近い整数に丸めます。

例:
22.22f * 100.0fのような結果になります2221.99993133544921875
したがって、期待値Convert.ToInt32切り上げ2222ますが、キャストは切り捨て2221ます。

45.11f * 100.0f一方、結果は aboutになり4511.00006103515625
これはを切り捨てConvert.ToInt32、直接キャストした場合と同じ結果になります。4511

于 2012-06-29T12:24:20.190 に答える
2

Botz3000の回答に続いて、MSDNの関連セクション:

Convert.ToInt32メソッド(シングル)

戻り値のタイプ:System.Int32値、最も近い32ビットの符号付き整数に丸められます。値が2つの整数の中間にある場合、偶数が返されます。つまり、4.5は4に変換され、5.5は6に変換されます。

明示的な数値変換テーブル

•double値またはfloat値から整数型に変換する場合、値はゼロに向かって最も近い整数値に丸められます。結果の積分値が宛先値の範囲外である場合、結果はオーバーフローチェックコンテキストによって異なります。チェックされたコンテキストでは、OverflowExceptionがスローされますが、チェックされていないコンテキストでは、結果は宛先タイプの指定されていない値になります。

于 2012-06-29T12:32:15.047 に答える
1

Convert.ToInt32を呼び出すことは、次を呼び出すことに似ています。

(int) Math.Round(floatValue, 0);

ダイレクトキャスティングは電話のようなものです

(int) Math.Floor(float);

Floorは常に、引数で指定した値以下の値を提供します。浮動小数点表現は「正確」ではありません。したがって、21.65は、十分な精度がないため、おそらく21.649999または同様のものとして表されます。

したがって、21.65 * 100 = 2164.9999この値をフローリングすると、2164.9以下の整数が得られます...つまり:2164

一方、2164.99を丸めると、次のようになります。2165

ここで効果を確認できます。

Console.WriteLine(Math.Round(21.65f*100));  //2165
Console.WriteLine(Math.Floor(21.65f*100));  //2164

floatの代わりにdoubleを使用する(より正確ですが、それでも無限ではありません):

Console.WriteLine(Math.Round(21.65d*100));  //2165
Console.WriteLine(Math.Floor(21.65d*100));  //2165
于 2012-06-29T12:36:13.360 に答える
1

この問題は、浮動小数点精度の不正確さ、特にfloat. を使用すると、問題が消えることがわかりますdecimal。ここには、10 進数と倍精度浮動小数点数 (および浮動小数点数) の違いに関する非常に良い答えがあります。- どれをいつ使用すればよいですか?

于 2012-06-29T12:24:46.453 に答える