1

I have 24 prices, one price for each hour of the day, and I need to find the average for them (the daily average).

But, I can't get the prices to average correctly, and I can't find an accurate algorithm on how to average prices/round decimals in Javascript. Every method (parseFloat, toFixed()) seems to produce inaccurate results occasionally.

Does anyone know the ACCURATE way to average prices/round decimals in Javascript? And I'm not just talking about something that works only with the array of prices below, but something that works and is bullet-proof with any array of prices (decimals)...

Here is what I have right now. It returns 178.00 in Chrome. But it should return 178.01.

// Rounding Function
function roundDecimal(value) {
    return Number(Math.round(value+'e2')+'e-2');
};

var priceSum    = 0;
var prices      = [23.4,24.4,24.68,25,25.1,30.81,851.19,646.47,659.24,707.7,759.23,124.69,37.93,53.25,23.4,23.8,23.4,23.4,50.57,37.78,25,24.55,23.4,23.73]

for(var x = 0; x < prices.length; x ++) {
     priceSum   = priceSum + prices[x];
    console.log(priceSum);
};

var priceAverage    = roundDecimal( priceSum / prices.length );

console.log("Daily Average is: "+priceAverage);
ac360
  • 7,735
  • 13
  • 52
  • 91

2 Answers2

3

Please refer to this question https://stackoverflow.com/a/588014/536984

JavaScript floating point math is not meant to do finance calculations, also is better that you represent your prices in cents, that way you don't have decimals

var array = [2340, 2440, 2468, 2500, 2510, 3081, 85119, 64647, 65924, 70770, 75923, 12469, 3793, 5325, 2340, 2380, 2340, 2340, 5057, 3778, 2500, 2455, 2340, 2373];

Math.round(array.reduce(function (a, b) { return a + b }) / array.length)
Community
  • 1
  • 1
Orlando
  • 9,374
  • 3
  • 56
  • 53
1

As said elsewhere, money is easiest with integers, but to get accuracy to a half cent, divide by the 100 to get cents again after dividing the total by the number of prices.

var prices= [23.4, 24.4, 24.68, 25, 25.1, 30.81, 851.19, 646.47, 659.24, 707.7, 759.23, 124.69, 37.93, 53.25, 23.4, 23.8, 23.4, 23.4, 50.57, 37.78, 25, 24.55, 23.4, 23.73];

var total=prices.map(function(n){
    return n*100;
}).reduce(function(a, b){
    return a+(b || 0);
});

Math.round((total/prices.length))/100;

/*  returned value: (Number)
178.01
*/
Orlando
  • 9,374
  • 3
  • 56
  • 53
kennebec
  • 102,654
  • 32
  • 106
  • 127