小编典典

如何使四舍五入的百分比加起来等于100%

algorithm

考虑以下四个百分比,以float数字表示:

    13.626332%
    47.989636%
     9.596008%
    28.788024%
   -----------
   100.000000%

我需要将这些百分比表示为整数。如果仅使用Math.round(),最终将占总数的101%。

14 + 48 + 10 + 29 = 101

如果使用parseInt(),我最终将获得97%的收益。

13 + 47 + 9 + 28 = 97

有什么好的算法可以将任意数量的百分比表示为整数,而总数量仍保持100%?


编辑 :阅读了一些评论和答案后,显然有很多方法可以解决此问题。

在我看来,为了忠于数字,“正确”的结果是使总误差最小化,该误差由相对于实际值的误差舍入将定义多少:

        value  rounded     error               decision
   ----------------------------------------------------
    13.626332       14      2.7%          round up (14)
    47.989636       48      0.0%          round up (48)
     9.596008       10      4.0%    don't round up  (9)
    28.788024       29      2.7%          round up (29)

在平局(3.33、3.33、3.33)的情况下,可以做出任意决定(例如3、4、3)。


阅读 794

收藏
2020-07-28

共1个答案

小编典典

由于这里的答案似乎都无法正确解决,因此这是我使用underscorejs的半混淆版本:

function foo(l, target) {
    var off = target - _.reduce(l, function(acc, x) { return acc + Math.round(x) }, 0);
    return _.chain(l).
            sortBy(function(x) { return Math.round(x) - x }).
            map(function(x, i) { return Math.round(x) + (off > i) - (i >= (l.length + off)) }).
            value();
}

foo([13.626332, 47.989636, 9.596008, 28.788024], 100) // => [48, 29, 14, 9]
foo([16.666, 16.666, 16.666, 16.666, 16.666, 16.666], 100) // => [17, 17, 17, 17, 16, 16]
foo([33.333, 33.333, 33.333], 100) // => [34, 33, 33]
foo([33.3, 33.3, 33.3, 0.1], 100) // => [34, 33, 33, 0]
2020-07-28