可变小数舍入



情况如下:

输入:

var a = 1.2567789m;
var b = 1.898436216m;
var c = 1.79863m;
var aD = 2;
var bD = 3;
var cD = 1;

结果:

var aR = 1.25m;  
var bR = 1.898m;
var cR = 1.7m;

所以输入的是不同的十进制数,有不同的小数位数和需要的位数。我需要将输入的数字四舍五入小数位数,每次小数位数都可能不同。我为此写了一个方法,效果很好,但我想知道是否有更好的解决方案:

static void Main(string[] args)
{
var a = 1.2567789m;
var b = 1.898436216m;
var c = 1.79863m;

var aD = 2;
var bD = 3;
var cD = 1;

Console.WriteLine(RoundDown(a, aD));
Console.WriteLine(RoundDown(b, bD));
Console.WriteLine(RoundDown(c, cD));
Console.ReadLine();
}

private static decimal RoundDown(decimal number, int decimals)
{
switch (decimals)
{
case 1:
{
return (Math.Truncate(number * 10)) / 10;
}
case 2:
{
return Math.Truncate(number * 100) / 100;
}
case 3:
{
return Math.Truncate(number * 1000) / 1000;
}
case 4:
{
return Math.Truncate(number * 10000) / 10000;
}
case 5:
{
return Math.Truncate(number * 100000) / 100000;
}
case 6:
{
return Math.Truncate(number * 1000000) / 1000000;
}
case 7:
{
return (Math.Truncate(number * 10000000)) / 10000000;
}
case 8:
{
return Math.Truncate(number * 100000000) / 100000000;
}
case 9:
{
return Math.Truncate(number * 1000000000) / 1000000000;
}
case 10:
{
return Math.Truncate(number * 10000000000) / 10000000000;
}
default: return 0;
}
}

提前非常感谢

您可以在循环中计算10 ** digits;然后按比例缩放,计算Floor并按比例缩小:

代码:

private static decimal MyFloor(decimal value, int digits = 0) {
decimal power = 1;

for (int i = 0; i < digits; ++i)
power = digits >= 0 ? power * 10 : power / 10;
return Math.Floor(value * power) / power;
}

演示:

var tests = new (decimal value, int digits)[] {
(1.2567789m, 2),
(1.898436216m, 3),
(1.79863m, 1)
};
string report = string.Join(Environment.NewLine, tests
.Select(test => $"Floor({test.value}, {test.digits}) = {MyFloor(test.value, test.digits)}"));
Console.WriteLine(report);

结果:

Floor(1.2567789, 2) = 1.25
Floor(1.898436216, 3) = 1.898
Floor(1.79863, 1) = 1.7

这些都需要

Math.Round()
Math.Floor()
Math.Ceiling()

虽然Dimitry的回答和往常一样出色,但Math.Round是这项工作的工具:

foreach( var x in new [] {( V: 1.2567789m, D: 2),(V: 1.898436216m, D: 3),(V: 1.79863m, D: 1)})
Console.WriteLine($"{x.V} @ {x.D} = {Math.Round(x.V, x.D, MidpointRounding.ToZero)}");

这产生:

1.2567789 @ 2 = 1.25
1.898436216 @ 3 = 1.898
1.79863 @ 1 = 1.7

最新更新