我需要为我正在构建的程序编写一个会计例程,它可以将小数除以整数。例如:
$143.13 / 5 =
28.62
28.62
28.63
28.63
28.63
我在这里看过这篇文章:在 c# 中均匀除法,但它似乎只适用于整数除法。对这个问题的优雅解决方案有任何想法吗?
我需要为我正在构建的程序编写一个会计例程,它可以将小数除以整数。例如:
$143.13 / 5 =
28.62
28.62
28.63
28.63
28.63
我在这里看过这篇文章:在 c# 中均匀除法,但它似乎只适用于整数除法。对这个问题的优雅解决方案有任何想法吗?
一次计算一个金额,然后从总数中减去每个金额,以确保您始终拥有正确的总数:
decimal total = 143.13m;
int divider = 5;
while (divider > 0) {
decimal amount = Math.Round(total / divider, 2);
Console.WriteLine(amount);
total -= amount;
divider--;
}
结果:
28,63
28,62
28,63
28,62
28,63
您可以在不构造数组的情况下解决这个问题(以美分为单位):
int a = 100 * amount;
int low_value = a / n;
int high_value = low_value + 1;
int num_highs = a % n;
int num_lows = n - num_highs;
处理美分更容易。我建议您将 14313 分成 5 个相等的部分,而不是 143.13。这给你 2862 和余数 3。你可以将这个余数分配给前三个部分或任何你喜欢的方式。最后,将美分兑换成美元。
另请注意,您得到的余数总是少于您想要的零件数。
首先,确保您不使用浮点数来表示美元和美分(请参阅其他帖子了解原因,但简单的原因是并非所有十进制数都可以表示为浮点数,例如,1.79 美元)。
这是一种方法:
decimal total = 143.13m;
int numberOfEntries = 5;
decimal unadjustedEntryAmount = total / numberOfEntries;
decimal leftoverAmount = total - (unadjustedEntryAmount * numberOfEntries);
int numberOfPenniesToDistribute = leftoverAmount * 100;
int numberOfUnadjustedEntries = numberOfEntries - numberOfPenniesToDistribute;
所以现在你有 28.62 的未调整数量,然后你必须决定如何分配剩余部分。您可以从顶部或底部开始为每个人分配额外的一分钱(看起来像您想要的从底部开始)。
for (int i = 0; i < numberOfUnadjustedEntries; i++) {
Console.WriteLine(unadjustedEntryAmount);
}
for (int i = 0; i < numberOfPenniesToDistribute; i++) {
Console.WriteLine(unadjustedEntryAmount + 0.01m);
}
您还可以将整个剩余部分添加到第一个或最后一个条目。最后,根据会计需要,您还可以为剩余部分创建单独的交易。
如果你有一个浮点数可以保证精确到两位数,那么这个(伪代码)呢:
amount = amount * 100 (convert to cents)
int[] amounts = new int[divisor]
for (i = 0; i < divisor; i++) amounts[i] = amount / divisor
extra = amount % divisor
for (i = 0; i < extra; i++) amounts[i]++
然后用amounts
美分做任何你想做的事情——如果你绝对需要的话,你可以转换回浮点数,或者格式化为美元和美分。
如果不清楚,所有这一切的重点不仅仅是平均分配浮动价值,而是尽可能平均分配货币金额,因为美分是美元的不可分割单位。致 OP:如果这不是你想要的,请告诉我。
也可以使用 C# 迭代器生成来使Guffa 的回答更方便:
public static IEnumerable<decimal> Divide(decimal amount, int numBuckets)
{
while(numBuckets > 0)
{
// determine the next amount to return...
var partialAmount = Math.Round(amount / numBuckets, 2);
yield return partialAmount;
// reduce th remaining amount and #buckets
// to account for previously yielded values
amount -= partialAmount;
numBuckets--;
}
}
您可以通过乘以 100,使用整数除法函数,然后将每个结果除以 100 来使用您引用的问题中的算法(假设您只想处理 2 dp,如果您想要 3dp 倍数乘以 1000 ETC)