我需要在C#和T-SQL中四舍五入十进制类型。四舍五入应考虑数字中的所有数字。例如:
rounding to tenths:
0.44 -> 0.4
0.45 -> 0.5
rounding to integer:
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#)可以按需工作。但不是。奇怪,但网上几乎没有有关该主题的信息。
Summary:应将每个数字的值逐步取整为0.45(和类似的值,例如0.44445),并得出1:
0.45 -> 0.50 -> 1.00.
是否有任何具有这种行为的标准C#和T-SQL函数?实现此目的的最佳方法是什么?
您可以通过循环来欺骗它:
double n = ...
int precision = 5;
while (precision >= 0) n = Math.Round(n, precision--);
return (int)n;
在四舍五入之前,将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);
Demo:
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