C#中的整数转换

时间:2012-06-29 12:16:40

标签: c# int

        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时值有时会有所不同,但并非总是如此。 有什么原因吗?

5 个答案:

答案 0 :(得分:9)

举一个例子,float格式的21.65实际上由21.6499999这样的数字表示。 Convert.ToInt32将数字四舍五入到最接近的整数,产生21.65,而显式转换(Int32)只是截断(向零舍入),因此得到21.64。

如果您希望浮点数在计算机中的显示方式与打印出来的方式相同,请使用decimal代替floatdouble

答案 1 :(得分:4)

Convert.ToInt32 rounds to the nearest integer,直接投射会截断数字。

因此,如果由于浮点不精确而使用2165.99999whatever而不是2165.0,则直接转换会在浮​​点之后截断所有值,而Convert.ToInt32则转向最接近整数。

例:
22.22f * 100.0f会产生类似2221.99993133544921875的内容 因此,Convert.ToInt32会将向上舍入到预期值2222,而广播会将其截断为2221

另一方面,

45.11f * 100.0f导致大约4511.00006103515625
其中Convert.ToInt32轮次向下,结果为4511,与直接投放时的结果相同。

答案 2 :(得分:2)

以下来自Botz3000的答案,来自MSDN的Relevent部分:

Convert.ToInt32 Method (Single)

  

返回值类型:System.Int32值,四舍五入到最接近的32位   有符号整数。如果值是两个整数之间的中间值,那么   偶数返回;也就是说,4.5转换为4,而5.5是   转换为6。

Explicit Numeric Conversions Table

  

•从double或float值转换为整数类型时,   该值向零舍入为最接近的整数值。如果   结果积分值超出目的地范围   值,结果取决于溢出检查上下文。在一个   检查上下文,在未选中时抛出OverflowException   上下文,结果是目标类型的未指定值。

答案 3 :(得分:1)

我认为您会发现问题是由浮点精度不准确造成的,特别是使用float。使用decimal时,您会发现问题消失。这里对decimal和double(和float)之间的差异有一个非常好的答案:decimal vs double! - Which one should I use and when?

答案 4 :(得分: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

使用双精度而不是浮点数(更精确,但仍然不是无限):

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