如何在 C# 中将 float 转换为 int,以便它输出与 float.ToString() 相同的值?
How to cast float to int in C# so that it outputs the same value as float.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"
如何将 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"
由于浮点数舍入,0.05f * 100
不完全是 5(它实际上是值 4.999998....当表示为 float
答案是,在 (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 的行为不同,对不精确的容忍度略高。
建议的另一种解决方案是使用 ToString 并解析字符串。当数字有小数点(或逗号)时,使用 Int32.Parse 会抛出异常,因此您必须只保留字符串的整数部分,并且可能会导致其他问题,具体取决于您的默认值 CultureInfo
。
在不精确的浮点数上调用 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"
0.05f * 100
不完全是 5(它实际上是值 4.999998....当表示为 float
答案是,在 (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 的行为不同,对不精确的容忍度略高。
CultureInfo
。