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

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

如果您希望浮点数在计算机中以与打印出来相同的方式表示,请使用ordecimal代替。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 answer之后,MSDN的相关部分:

Convert.ToInt32 方法(单个)

返回值 类型:System.Int32 值,四舍五入到最接近的 32 位有符号整数。如果 value 在两个整数的中间,则返回偶数;即4.5转换为4,5.5转换为6。

显式数值转换表

• 当您从双精度或浮点值转换为整数类型时,该值将向零舍入到最接近的整数值。如果生成的整数值超出目标值的范围,则结果取决于溢出检查上下文。在已检查的上下文中,会引发 OverflowException,而在未检查的上下文中,结果是目标类型的未指定值。

于 2012-06-29T12:32:15.047 回答
1

我想你会发现问题是由浮点精度不准确引起的,特别是使用float. 您会发现使用decimal. 关于十进制和双精度(和浮点)之间的区别有一个非常好的答案:十进制与双精度!- 我应该使用哪一个以及何时使用?

于 2012-06-29T12:24:46.453 回答
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
于 2012-06-29T12:36:13.360 回答