【问题标题】:C#, SQL Server : rounding [closed]C#,SQL Server:四舍五入[关闭]
【发布时间】:2019-12-26 11:41:34
【问题描述】:

我需要在 C# 和 T-SQL 中对小数类型进行四舍五入。四舍五入应考虑数字中的所有数字。

例如:

四舍五入:

0.44 -> 0.4
0.45 -> 0.5

四舍五入到整数:

0.44 -> 0.0
0.45 -> 1.0

标准方法不适合:

-- T-SQL
print round(0.44, 1) ---> 0.40 Nice
print round(0.45, 1) ---> 0.50 Nice
print round(0.44, 0) ---> 0.00 Nice
print round(0.45, 0) ---> 0.00 Bad (need 1.00)

// C#
Console.WriteLine(Math.Round(0.44m, 1, MidpointRounding.AwayFromZero)); //-> 0.40 Nice
Console.WriteLine(Math.Round(0.45m, 1, MidpointRounding.AwayFromZero)); //-> 0.50 Nice
Console.WriteLine(Math.Round(0.44m, 0, MidpointRounding.AwayFromZero)); //-> 0.00 Nice
Console.WriteLine(Math.Round(0.45m, 0, MidpointRounding.AwayFromZero)); //-> 0.00 Bad (need 1.00)

之前,我相信 round (T-SQL) 和 Math.Round (C#) 可以满足我的需要。但不是。奇怪,但网上几乎没有关于这个主题的信息。

总结:值 0.45(以及类似的值,例如 0.44445)应逐位向上舍入并导致 1:

0.45 -> 0.50 -> 1.00.

四舍五入的整数部分并不总是0。可能是1.2.3 ... 100。

是否有任何具有这种行为的标准 C# 和 T-SQL 函数?

实现这一点的最佳方法是什么?


更新

为什么需要这样做? 我的客户使用许多需要四舍五入的指标。每个指标显示用户在其工作中的成功。所描述的方法将改进这些指标。改进将使客户和用户都受益。因此,考虑了这种舍入选项。

我同意舍入在数学上不正确的观点。由于 0.45 和舍入 0.5 的值都以显式形式出现在程序中,这导致了我的错误。 C# 和 T-SQL 函数正常工作。

【问题讨论】:

  • 为什么0.45 会舍入到1?它小于0.5,所以它四舍五入到0。没错。
  • 你为什么期待round(0.45, 0) 结果为10.45 小于 0.50
  • 那么数字0.444444444444445 是否也将四舍五入为1?但是,0.4444444344445 会舍入到0为什么?这不是四舍五入的工作原理。
  • 除了阐明您想要什么之外,我强烈建议您提出两个单独的问题 - 一个针对 C#,另一个针对 SQL。
  • @JonSkeet,感谢您的建议。我提供了一个解释。感谢 StackOverflow 用户的意见和回答。够了。如果问题发展,我会将问题分为两个分支。

标签: c# sql-server tsql rounding


【解决方案1】:

你可以用循环来欺骗它:

double n = ...
int precision = 5;
while (precision >= 0) n = Math.Round(n, precision--);

return (int)n;

【讨论】:

  • 好答案!精度的初始值(你有 5)应该大于或等于小数点后的有效位数。精度的最终值(您有 0)应该是所需的最终精度(即问题示例中的 0 或 1)。
  • 谢谢,也许这个选项适合我。
【解决方案2】:

在舍入前尝试 9 / 8 因子:

  round(0.45, 1)         -> round(0.45 * 9 / 8, 1)         -- T-SQL

  Math.Round(0.45m, ...) -> Math.Round(0.45m * 9 / 8, ...) // C#

C# 代码

  Func<double, int, double> round = (value, digits) =>
     Math.Round(value * 9 / 8, digits, MidpointRounding.AwayFromZero);

演示:

  double[] tests = new double[] {
    0.44,
    0.45,
  };

  string result = string.Join(Environment.NewLine, tests
    .Select(test => $"{test} => {round(test, 1)}")
    .Concat(tests
    .Select(test => $"{test} => {round(test, 0)}")));

  Console.Write(result);

结果:

0.44 => 0.5
0.45 => 0.5
0.44 => 0
0.45 => 1

【讨论】:

  • 对不起,描述的情况不清楚。四舍五入的整数部分并不总是0。可能是1.2.3 ... 100。感谢您的回答
猜你喜欢
  • 1970-01-01
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
相关资源
最近更新 更多