克服分歧
本文关键字:克服 | 更新日期: 2023-09-27 18:17:03
我用下面的代码将一个金额除以一个数字,并将结果分配为每月需要支付的金额。
objData.month_per_amount = (Convert.ToDecimal(txtAmount.Value) / Convert.ToInt32(txtMonths.Value));
在一个场景示例中,如果我将13除以3并将结果四舍五入到小数点后两位,那么每个月得到4.33。但是当我把4.33乘以3,得到12.99,它不等于13。差异为0.01。在这种情况下,我如何分配如下:
month 1: 4.33第二个月:4.33第3月:4.34
希望我说得很清楚,首选代码应该只在有这样的差异时执行,例如,如果14除以2,我们每个月得到7,7+7=14,所以我们在这里得到的数字完全相同。
在会计中,你经常使用"减少余额"来表示这一点。其思路是计算当月的总金额,从总金额中扣除,减少月数。比如:
decimal balance = 13m;
int months = 3;
int monthsRemaining = 3;
for (var i = 0; i < months; i++)
{
decimal thisMonth = Math.Round(balance / monthsRemaining, 2);
balance -= thisMonth;
monthsRemaining -= 1;
Console.WriteLine("Month {0}: {1}", i + 1, thisMonth);
}
结果为4.33,4.34,4.33。
这种方法的好处是舍入误差在整个期间均匀分布,而不是在一个月内全部分布。例如,使用该方法,24个月内100将导致23笔4.17的付款和1笔4.09的付款,而每月减少余额将为4.16或4.17。
您不必检查余数。一个更高效的c#代码(就所需的计算量而言)应该是这样的:
double amount = 13;
int months = 3;
int precision = 2;
double[] amountForEachMonth = new double[months];
double temp = Math.Round(amount / months, precision);
for (int i = 0 ; i < months - 1 ; i++)
amountForEachMonth[i] = temp;
amountForEachMonth[months - 1] = amount - (temp * (months - 1)) ;
当存在差异时,您不需要将其作为特殊情况,您可以简单地将最后一个月的付款计算为剩余付款以达到总金额。如果没有差异,那么无论如何它都会是相同的值。例子:
int months = Convert.ToInt32(txtMonths.Value);
decimal amount = Convert.ToDecimal(txtAmount.Value);
month_per_amount = Decimal.Round(amount / months, 2);
decimal last_month = amount - (months - 1) * month_per_amount;
for (int month = 1; month <= months; month++) {
decimal monthly = month < months ? month_per_amount : last_month;
Console.WriteLine("Month {0}: {1}", month, monthly);
}
如果" amount % month == 0 ",则无差异。否则,最后一项应该比其他项多一点。(这里的代码可能有一些语法问题,我想向您展示算法。)
decimal amount = Convert.ToDecimal(txtAmount.Value);
int month = Convert.ToInt32(txtMonths.Value);
int n = 3;
decimal amounts[3];//n = 3
for (int i = 0 ; i < n-1 ; i++)
amounts[i] = amount / month;
if ( amount % month != 0 ) {
amounts[n-1] = amount - ( amount / month * (n-1) ) ;
else
amounts[n-1] = amount / month ;