如何在C#中将float转换为int,以便它输出与float.ToString()相同的值?

时间:2018-05-02 10:50:37

标签: c# floating-point floating-accuracy

在不精确浮点数上调用ToString()会产生人类期望的数字(例如4.999999 ...打印为5)。但是,当转换为int时,小数部分会被删除,结果是整数减1。

float num = 5f;
num *= 0.01f;
num *= 100f;
num.ToString().Dump(); // produces "5", as expected
((int)num).ToString().Dump(); // produces "4"

如何将float转换为int,以便获得float.ToString()生成的人类友好值?

我正在使用这个肮脏的黑客:

int ToInt(float value) {
    return (int)(value + Math.Sign(value) * 0.00001);
}

..但肯定必须有一个更优雅的解决方案。

编辑:我非常清楚为什么浮点数被截断的原因(4.999 ...到4等)问题是在模拟默认行为时转换为int System.Single.ToString()

为了更好地说明我正在寻找的行为:

-4.99f应该施放到-4
4.01f应该转换为4
4.99f应该转为4
4.999999f应该转为4
4.9999993f应该转换为 5

这与ToString产生的完全相同的行为。

尝试运行:

float almost5 = 4.9999993f;
Console.WriteLine(almost5); // "5"
Console.WriteLine((int)almost5); // "4"

3 个答案:

答案 0 :(得分:2)

也许你正在寻找这个:

Convert.ToInt32(float)

source

答案 1 :(得分:1)

由于浮点舍入,

0.05f * 100并不完全是5(它实际上是值4.999998 ....表示为浮点数

答案是,在(int)(.05f * 100)的情况下,您将浮点值4.999998并将其截断为整数,从而产生4

因此请使用Math.Round。 Math.Round函数将浮点值舍入为最接近的整数,并将中点值舍入为最接近的偶数。

    float num = 5f;
    num *= 0.01f;
    num *= 100f;
    Console.WriteLine(num.ToString());
    Console.WriteLine(((int)Math.Round(num)).ToString());

答案 2 :(得分:0)

到目前为止,最佳解决方案似乎是问题中的解决方案。

int ToInt(float value) {
    return (int)(value + Math.Sign(value) * 0.000001f);
}

如果差异足够小(小于0.000001),这会有效地将值捕捉到最接近的int。但是,此函数与ToString的行为不同,并且稍微容忍不精确。

@chux建议的另一个解决方案是使用ToString并将字符串解析回来。当数字有一个小数点(或逗号)时,使用Int32.Parse会抛出异常,因此您必须只保留字符串的整数部分,这可能会导致其他麻烦,具体取决于您的默认CultureInfo