将float转换为整数时出现.NET错误?

时间:2008-11-03 20:46:53

标签: .net floating-point

检查一下:这个小的.NET控制台程序会产生有趣的结果......请注意我是如何以两种不同的方式将浮点数转换为整数:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CastVsConvert
{
    class Program
    {
        static void Main(string[] args)
        {
            int newWidth = 0;
            CalculateResizeSizes(600, 500, out newWidth);
        }

        static void CalculateResizeSizes(int originalWidth, int maxWidth, out int newWidth)
        {
            float percentage = 1.0F;
            percentage = maxWidth / (float)originalWidth;

            newWidth = (int)((float)originalWidth * percentage);
            int newWidthConvert = Convert.ToInt32((float)originalWidth * percentage);

            Console.Write("Percentage: {0}\n", percentage.ToString());
            Console.Write("Cast: {0}\n", newWidth.ToString());
            Console.Write("Convert: {0}\n", newWidthConvert.ToString());
        }
    }
}

我希望“Cast”和“Convert”的输出相同,但它们不是......这是输出:

C:\Documents and Settings\Scott\My Documents\Visual Studio 2008\Projects\CastVsC
onvert\CastVsConvert\bin\Debug>CastVsConvert.exe
Percentage: 0.8333333
Cast: 499
Convert: 500

有人知道为什么.NET会在这里返回不同的值吗?

4 个答案:

答案 0 :(得分:14)

它不是一个错误,cast截断,convert轮。

请参阅this

答案 1 :(得分:5)

当转换为四舍五入时,演员正在切掉小数点后面的数字部分。

答案 2 :(得分:5)

来自Convert.ToInt32的返回值的文档:

  

value 四舍五入为最接近的32位有符号整数。如果价值是中途   在两个整数之间,偶数   号码被退回;也就是说,4.5是   转换为4,转换为5.5   到6。

投射不会向上舍入 - 它只是截断。乘法的结果略低于500,因此转换将截断为499,而Convert.ToInt32将其舍入为500。

答案 3 :(得分:1)

有一个额外的,隐藏的演员可能会导致这个。例如,如果您使用此而不是重新计算:

int newWidthConvert = Convert.ToInt32(newWidth);

你会得到相同的结果。当您使用Reflector查看Convert.ToInt32(float)

时,发生的事情变得更加清晰
public static int ToInt32(float value)
{
    return ToInt32((double) value);
}

Double有一个隐藏的演员。

如果您添加几行进行调查,请使用调试器来查看,您会看到会发生什么:

float newWidth1 = ((float)originalWidth * percentage);
double newWidth2 = ((float)originalWidth * percentage); 

double更精确,并将值保存为499.999999和更多的十进制数字。 float不太精确,存储500.0。整数转换会截断小数部分,因此基于中间强制转换最终会得到500或499。当您致电Convert.ToInt32()时,结果已投放到float,因此您获得了500.0的Double表示。我个人更喜欢在可以的时候总是使用double