银行家算法实现百分比计算结果求和100

需求:对一组数计算其中每一项相对整体占比。

问题:单纯采取四舍五入保留精度方式会导致各项占比累加不为100。

银行家算法介绍:采用四舍六入五留双,当舍去位的数值小于5时,直接舍去该位;当舍去位的数值大于等于6时,在舍去该位的同时向前位进一;当舍去位的数值等于5时,如果前位数值为奇,则在舍去该位的同时向前位进一,如果前位数值为偶,则直接舍去该位。

参考地址:https://blog.csdn.net/qq_38523017/article/details/83989543

   // valueList: [22, 33, 44]
  // idx 当前项 索引 0, 1, 2
  // precision 精度 2
  const getPercentWithPrecision= (valueList, idx, precision) => { if (!valueList[idx]) { return 0; } let sum = valueList.reduce(function (acc, val) { return acc + (isNaN(val) ? 0 : val); }, 0); if (sum === 0) { return 0; } let digits = Math.pow(10, precision); let votesPerQuota = valueList.map(function (val) { return ((isNaN(val) ? 0 : val) / sum) * digits * 100; }); let targetSeats = digits * 100; let seats = votesPerQuota.map(function (votes) { return Math.floor(votes); }); let currentSum = seats.reduce(function (acc, val) { return acc + val; }, 0); let remainder = votesPerQuota.map(function (votes, idx) { return votes - seats[idx]; }); while (currentSum < targetSeats) { let max = Number.NEGATIVE_INFINITY; let maxId = null; for (let i = 0, len = remainder.length; i < len; ++i) { if (remainder[i] > max) { max = remainder[i]; maxId = i; } } ++seats[maxId]; remainder[maxId] = 0; ++currentSum; } return seats[idx] / digits; }

 

posted @ 2020-11-30 16:55  eightabs  阅读(360)  评论(0编辑  收藏  举报