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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (194)

考虑以下四个百分比,表示为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)。

提问于
用户回答回答于

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]
用户回答回答于

第一个也可能是最流行的方法是最大余数法

基本上是:

  1. 把所有的东西都包围起来
  2. 得到和100的差额
  3. 通过在项目中添加1以其小数点的递减顺序分配差额

在你的例子中,情况会是这样的:

13.626332%
47.989636%
 9.596008%
28.788024%

如果取整数部分,就会得到

13
47
 9
28

这等于97,你还想再加三个。现在,看看十进制部分,它们是

.626332%
.989636%
.596008%
.788024%

取最大的,直到总数达到100。所以你会得到:

14
48
 9
29

或者,可以选择只显示一个小数位,而不是整数值。所以数字是48.3和23.9等等。这将使差异从100大幅度下降。

扫码关注云+社区