可变小数舍入
Variable decimal rounding
情况如下:
输入:
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
情况如下:
输入:
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