Reputation: 1672
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
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
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