Leon van der Veen
Leon van der Veen

Reputation: 1672

Rounding problems in JavaScript

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?

Upvotes: 2

Views: 105

Answers (2)

JLRishe
JLRishe

Reputation: 101758

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

Upvotes: 1

meskobalazs
meskobalazs

Reputation: 16041

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.

Upvotes: 0

Related Questions