因此,当我尝试向上或向下舍入浮点值时。现在,我目前使用此代码:
var calc_points = (distance_in_km - total_dist) * 20;
Debug.WriteLine("Negatief! " + calc_points);
points = (int)Math.Abs(calc_points);
distance_in_km
是float
,total_dist
是float
。
我在这里做什么错了?
in和输出的示例;
0.33425 => 0
-0.33425 => 0
1.44445 => 2
-1.44445 => -2
3.2954 => 3
-3.2954 => -3
这是基础数学,但是我不知道应该如何在代码中执行此操作,因为Math.Round()
不是“正常”数学。...
答案 0 :(得分:2)
如果您想将value
进行四舍五入,请放Math.Round:
float value = -1.999969f;
// Scale: value / 10 then round up to 1 digit after the decimal point (-0.2)
double result = Math.Round(value / 10.0, 1);
如果您只想代表 value
(我们希望保持value
不变,但只将小数点后一位数字打印出来),请使用格式({F1
格式字符串-小数点后1
位)
float value = -1.999969f
// Scale and then represent with 1 digit after the decimal point (-0.2)
Debug.WriteLine($"Negatief! {value / 10.0:F1}");
编辑::如果要特殊种类四舍五入(请参见问题注释):
例如,如果您有
后面1.44446
,则应将其四舍五入为2,因为6
比5
大,因此得到1.4445
,然后再舍入到1.445
, 因为如果5
或更大,则向上取整,依此类推,直到不再有数字.
我们必须发明公式。如我们所见
0.444444....444 -> 0
0.444444....445 -> 1
这意味着我们可以使Math.Round
适应这些规则:为了将0.(4)
推到0.5
,我们可以将小数部分乘以1.25
:
0.44444...444 * 1.25 = 0.5
示例代码:
private static int MyRound(double value) {
return (int)value + (int)Math.Round((value - (int) value) * 1.125);
}
或者,如果我们想要double
作为结果
private static double MyRound(double value) {
return Math.Truncate(value) + Math.Round(value % 1 * 1.125);
}
测试:
double[] tests = new double[] {
1.44446,
1.4444,
-1.44444,
-1.4445,
0.33425,
-0.33425,
3.2954,
-3.2954,
};
string report = string.Join(Environment.NewLine, tests
.Select(item => $"{item,10} => {MyRound(item),2}"));
Console.Write(report);
结果:
1.44446 => 2
1.4444 => 1
-1.44444 => -1
-1.4445 => -2
0.33425 => 0
-0.33425 => 0
3.2954 => 3
-3.2954 => -3
答案 1 :(得分:1)
您似乎想要的是某种类型的“渐进式”四舍五入,在这种情况下,每次将四舍五入至小数点后0位。为此,您实际上必须一次舍入一位。
以扩展方法实现:
using System.Data.SqlTypes;
public static double GradualRoundingTo0(this double d) {
var dp = ((SqlDecimal)(Decimal)d).Scale;
return Enumerable.Range(1, dp).Aggregate(d, (a, n) => Math.Round(a, dp - n, MidpointRounding.AwayFromZero));
}
您将需要using
来实现我用来计算舍入小数位数的技巧。