由于没有更好的词,我需要一种方法来在一个或多个“桶”之间分配金额(以美元计)。它需要具有标准的小数点后两位精度,但每一分钱都需要计算在内。
为了说明这个问题,考虑这个例子:
200 美元分成 3 种方式。如果向下取整,每笔金额为 66.66 美元,您最终会少 2 美分,但如果向上取整,每笔金额为 66.67 美元,您多出 2 美分。答案当然是一个 66.66 美元,另外两个 66.67 美元。这对人类来说很容易推理,但试图让一点 JavaScript 理解这是一种挑战。
由于没有更好的词,我需要一种方法来在一个或多个“桶”之间分配金额(以美元计)。它需要具有标准的小数点后两位精度,但每一分钱都需要计算在内。
为了说明这个问题,考虑这个例子:
200 美元分成 3 种方式。如果向下取整,每笔金额为 66.66 美元,您最终会少 2 美分,但如果向上取整,每笔金额为 66.67 美元,您多出 2 美分。答案当然是一个 66.66 美元,另外两个 66.67 美元。这对人类来说很容易推理,但试图让一点 JavaScript 理解这是一种挑战。
这是我想出的功能:
function SplitTotal( totalAmount, numberToSplit, precision ) {
var precisionFactor = Math.pow(10, precision);
var remainderFactor = 1 / precisionFactor;
var splitAmount = Math.ceil( totalAmount / numberToSplit * precisionFactor ) / precisionFactor;
var remainder = Math.round( (splitAmount * numberToSplit - totalAmount) * precisionFactor ) / precisionFactor;
var result = [];
for (var i = 0; i < numberToSplit; i++) {
result.push( (remainder >= remainderFactor) ?
Math.round( (splitAmount - remainderFactor) * precisionFactor ) / precisionFactor :
splitAmount );
remainder = Math.round( (remainder - remainderFactor) * precisionFactor ) / precisionFactor;
}
return result;
}
代码有点复杂,因为 JavaScript 处理浮点数非常糟糕。为了得到一个很好的、精确的小数,你需要将这个数量乘以我在这里所说的“精度因子”,它只是 10 的某个指数,将结果数字四舍五入,然后除以该精度因子得到回到原来的十进制精度。
尽管我只需要 2 个小数位的精度,但我使精度很容易定义,因此这适用于更多的应用程序,而不仅仅是美元金额。如果只需要整数,则可以指定精度为 0。
例如:235.38 美元分为 7 种方式:
> SplitTotal(235.38, 7, 2)
[33.62, 33.62, 33.62, 33.63, 33.63, 33.63, 33.63]