2

I've got a problem with rounding in JavaScript. I'm using a function for rounding:

function roundup(rnum, rlength){
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

var amount = roundup(2253.825, 3);

Strange thing is, when I round up the number 2253.825, the result is 2253.82 which has to be 2253.83. When I round up the number 5592.825 the result is 5592.83, which is correct.

Any idea how to fix this?

meskobalazs
  • 15,741
  • 2
  • 40
  • 63
Leon van der Veen
  • 1,652
  • 11
  • 42
  • 60

2 Answers2

1

Floating point rounding errors are at fault here. 2620.825 * 100 is 262082.49999999997, so when you round it, the result is 262082.

Here is a more robust approach that corrects for this:

function roundup(rnum, rlength) {
    var shifted = rnum * Math.pow(10, rlength),
        rounded = Math.round(shifted),
        delta = Math.abs(shifted - rounded);

    if (delta > 0.4999999 && delta < 0.5) {
        rounded += (rounded < 0 ? -1 : 1);
    }

    return rounded / Math.pow(10, rlength);
}

console.log("2620.825 :=> " + roundup(2620.825, 2));
console.log("2621.825 :=> " + roundup(2621.825, 2));
console.log("2620.8255 :=> " + roundup(2620.8255, 2));
JLRishe
  • 99,490
  • 19
  • 131
  • 169
0

The problem shows up inherently because the way IEEE 754 doubles work. If you really want to always get mathematically correct results, you need to use a custom datatype, for example a BigDecimal implementation like this one.

Please also take a look at this answer, as it may be useful.

Community
  • 1
  • 1
meskobalazs
  • 15,741
  • 2
  • 40
  • 63