JavaScript - 将3个数字转换为百分比,不会产生100%的总数

时间:2016-08-04 14:21:39

标签: javascript math rounding percentage tofixed

我有一个场景,我有三个数字:

  1. 17
  2. 10
  3. 90
  4. 我需要将它们转换为整个百分比值(这样当添加时,总计100%就像你期望的那样)。我有这个功能:

    function roundPercentageTotals(num1, num2, num3) {
        var total = num1 + num2 + num3;  // 117
    
        var num1Total = (num1 / total) * 100;  // 14.529914529914531
        var num2Total = (num2 / total) * 100;  //  8.547008547008546
        var num3Total = (num3 / total) * 100;  // 76.92307692307693
    
        var num1ToDecimal = num1Total.toFixed(1); // 14.5
        var num2ToDecimal = num2Total.toFixed(1); //  8.5
        var num3ToDecimal = num3Total.toFixed(1); // 76.9
    
        var totalPercentage = parseInt(num1ToDecimal) + parseInt(num2ToDecimal) + parseInt(num3ToDecimal); // 98
    
        return { percentage1: Math.round(num1ToDecimal, percentage2: Math.round(num2ToDecimal), percentage3: Math.round(num3ToDecimal) };
    }
    

    在我的例子中,计算的总百分比是98%。其次是:

    1. 百分比1 = 15
    2. 百分比2 = 9
    3. 百分比3 = 77
    4. 其中加起来高达101%,我哪里错了?

      提前感谢您的帮助!

4 个答案:

答案 0 :(得分:6)

你在第一次计算中获得了98%,因为你将值向下舍入,然后在第二次计算中得到101%,因为你将它们四舍五入 up

将您的<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp" ng-controller="MyCtrl"> <input type="text" test ng-model="test" /> </div>更改为parseInt(),使您的总数接近100%而不是98%。 parseFloat()小数点,它不会围绕它们。

关于你的第二次计算总计101%:通过四舍五入到15.5和8.5到9,你刚刚增加了1%。这使你得到101%而不是100%。

最重要的是,如果你想要确切的数值,你不可能始终如一地达到100%,除非你捏造你的百分比以适应前方的某个地方。

答案 1 :(得分:2)

好的,所以看起来像数学,我无法达到我想要的。但是,我需要将数字向上舍入到最终等于100%(所有这些都是圆形的数字,所以不完全准确)。

这是我的解决方案,以防这对其他人有用:

function roundPercentageTotals(numArr) {

    // Total of all numbers passed.
    var total = numArr[0] + numArr[1] + numArr[2];

    // Percentage representations of each number (out of 100).
    var num1Percent = Math.round((numArr[0] / total) * 100);
    var num2Percent = Math.round((numArr[1] / total) * 100);
    var num3Percent = Math.round((numArr[2] / total) * 100);

    // Total percent of the 3 numbers combined (doesnt always equal 100%).
    var totalPercentage = num1Percent + num2Percent + num3Percent;

    // If not 100%, then we need to work around it by subtracting from the largest number (not as accurate but works out).
    if (totalPercentage != 100) {
        // Get the index of the largest number in the array.
        var index = getLargestNumInArrayIndex(numArr);

        // Take the difference away from the largest number.
        numArr[index] = numArr[index] - (totalPercentage - 100);

        // Re-run this method recursively, until we get a total percentage of 100%.
        return roundPercentageTotals(numArr);
    }

    // Return the percentage version of the array passed in.
    return [num1Percent, num2Percent, num3Percent];
}

function getLargestNumInArrayIndex(array) {
    return array.indexOf(Math.max.apply(Math, array));
}

将一组数字传递给roundPercentageTotals,例如roundPercentageTotals([13,54,38]),它将返回数组中的整个百分比(或我应该说的最接近的百分比)。

答案 2 :(得分:1)

您无法以百分比形式转换这些数字而不包含小数。它只有在数字除以100时才有效。所以答案必须是(1. 14.5,2。8.5,3.66.9)。正如你所看到的,有一个&#34; 0.1&#34;因为你投掷小数的原因相同而丢失了百分比(即将14.529914529914531转换为14.5)。

答案 3 :(得分:1)

percent-round就是这样做的。为我做了工作。 只需传递值并取回始终总计为100%的百分比即可。

const percentRound = require ('percent-round');
percentRound([16, 56, 18]); // [18, 62, 20]