1. ホーム

[解決済み】丸められたパーセンテージを100%にする方法

2022-04-18 16:34:15

質問

以下の4つのパーセンテージを考えてみましょう。 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%に保ちつつ、任意の数のパーセンテージを整数で表現する良いアルゴリズムは?


編集 : いくつかのコメントと回答を読んだ後、これを解決するために行くには明らかに多くの方法があります。

私の考えでは、数字に忠実であるために、quot;right"の結果は、実際の値に対して丸め誤差がどれくらい発生するかで定義される、全体の誤差を最小化するものです。

        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)。

どのように解決するのですか?

ここにあるどの回答も適切に解決していないようなので、以下は私の半難読化バージョンです。 アンダースコアjs :

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]