Search code examples
javascriptfloating-point-precision

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?


Solution

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