舍入负数上下浮动,具体取决于逗号后面的值

时间:2018-08-29 22:00:35

标签: c# math floating-point

因此,当我尝试向上或向下舍入浮点值时。现在,我目前使用此代码:

var calc_points = (distance_in_km - total_dist) * 20;
Debug.WriteLine("Negatief! " + calc_points);
points = (int)Math.Abs(calc_points);

distance_in_kmfloattotal_distfloat

我在这里做什么错了?

in和输出的示例;

 0.33425 =>  0
-0.33425 =>  0
 1.44445 =>  2
-1.44445 => -2
 3.2954  =>  3
-3.2954  => -3

这是基础数学,但是我不知道应该如何在代码中执行此操作,因为Math.Round()不是“正常”数学。...

2 个答案:

答案 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,因为   65大,因此得到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来实现我用来计算舍入小数位数的技巧。