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



在不精确的浮点数上调用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"

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

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

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

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


编辑:我很清楚浮点数被截断的原因(4.999... 到 4 等(问题是关于在模拟 System.Single.ToString(( 的默认行为时强制转换为int

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

-4.99f 应转换为 -4 4.01f 应转换为 4 4.99f 应转换为 4 4.999999f 应转换为 44.9999993F



应转换为5

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

尝试运行以下命令:

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

也许你正在寻找这个:

Convert.ToInt32(float(

由于浮点舍入,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());

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

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

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

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

最新更新