C# 根据逗号后面的值向上或向下舍入负浮点

C# 根据逗号后面的值向上或向下舍入负浮点,c#,math,floating-point,C#,Math,Floating Point,所以当我试图向上或向下舍入一个浮点值时。现在我正在使用以下代码: var calc_points = (distance_in_km - total_dist) * 20; Debug.WriteLine("Negatief! " + calc_points); points = (int)Math.Abs(calc_points); 其中,距离(单位:千米)是一个浮动,总距离是一个浮动 我做错了什么 输入和输出的示例 0.33425 => 0 -0.33425 => 0

所以当我试图向上或向下舍入一个浮点值时。现在我正在使用以下代码:

var calc_points = (distance_in_km - total_dist) * 20;
Debug.WriteLine("Negatief! " + calc_points);
points = (int)Math.Abs(calc_points);
其中,
距离(单位:千米)
是一个
浮动
总距离
是一个
浮动

我做错了什么

输入和输出的示例

 0.33425 =>  0
-0.33425 =>  0
 1.44445 =>  2
-1.44445 => -2
 3.2954  =>  3
-3.2954  => -3
这是基础数学,但我不知道如何在代码中实现这一点,因为
Math.Round()
不是“正常”数学….

如果要对
值进行四舍五入,请输入:

如果您只想表示
(我们希望保持
不变,但只在小数点后打印一位),请使用格式(
F1
格式字符串-
1
小数点后的数字)

编辑:如果需要特殊类型的舍入(请参阅问题的注释):

例如,如果您有
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);
  }
或者,如果我们想要双倍的

  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

您似乎想要的是某种类型的“渐进式”舍入,即每次少舍入一位,直到小数点后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));
}

您需要使用
来实现我用来计算舍入小数位数的技巧。

舍入通常不会引入10的因子。。。但是如果你想要的是一个10的因子,可以简单地尝试
Math.Round(input)/10
。如果你想要一个特定的舍入,请提供更多的例子好吗?特别是与标准的
数学.舍入
行为和边界情况的差异(例如
-1.5
-2.5
?)这不是任何舍入定义的工作方式。如果需要非正常舍入,则需要为所有输入提供特定规则。另外,在您的示例代码中,您希望“舍入”发生在哪里?我在这里做错了什么?您对“舍入”的要求/定义不是正常舍入所代表的。首先应该正确定义这些。你的例子不一致。你说的是
0.33425=>0
,但是
1.445=>2
。两者中的小数部分都小于一半,所以通常它们应该四舍五入。这个舍入标准基于什么?换句话说,如果
0.33425
向下取整,那么
1.445
也应该如此<代码>System.Math.Round(n,2,中点舍入.AwayFromZero);//3.15
@Robin:嗯,
数学四舍五入(-1.444469,2,中点四舍五入。远离零)返回<代码> -1.44 当你把“它需要是代码> -0.1 < /代码>”@ Robin:<代码>中点点数< /代码>如果我们正好在中间,例如“代码>数学。圆(-2.5,0,中点点数,AWAY0)==-3<3)/代码>当<代码>数学回合(-2.5,0,中点点数,to-)==-2 < /代码>;很抱歉,我无法从问题中的示例中推导出正确的
中点舍入
。我不知道您认为舍入是什么意思,但您用错了。
(int)value+(int)Math.round((value-(int)value)*1.125)在这里成功了!谢谢
   1.44446 =>  2
    1.4444 =>  1
  -1.44444 => -1
   -1.4445 => -2
   0.33425 =>  0
  -0.33425 =>  0
    3.2954 =>  3
   -3.2954 => -3
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));
}