JavaScript Number Rounding

Numbers don’t add up!

0.1 + 0.2 = 0.30000000000000004

Sometimes numbers in JavaScript (and other languages) simply don’t appear to add up. Don’t believe me?.

0.1 + 0.2 = 0.30000000000000004
1
2
3
4
5
6
var x = 0.1,
y = 0.2;
var result = x + y;
console.log(result);

I discovered this in the early days of programming when building a JavaScript calculator, which fortunately is now nowhere to be seen :)

Floating point numbers

JavaScript uses Floating Point Numbers, which don’t cater for an accurate representations of a decimal. This means that as soon as the variable is interpreted at runtime, a rounding issue is introduced. Computers are faster and more efficient at dealing with computations on binary numbers, which produces the issue with the 17th decimal place.

How to fix it

Here’s an example of how I eliminate the rounding issues.

0.1 + 0.2 = 0.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = 0.1,
y = 0.2;
var multiplier = function (dec) {
var str = dec.toString(),
match = /(?:\.(\d+))?(?:[eE]([+\-]?\d+))?$/.exec(str);
return Math.max(0, (match[1] == '0' ? 0 : (match[1] || '').length) - (match[2] || 0)) * 10;
};
var highestMultiplier = Math.max(multiplier(x), multiplier(y));
var result = ((x * highestMultiplier) + (y * highestMultiplier)) / highestMultiplier;
console.log(result);

Essentially, I’m calculating the smallest number, which if multiplied by either number I’m adding together individually, would result in an integer. This is achieved by evaluating the number with the most numbers after the decimal point and what that value is. Once I have the multiplier, I use it on both the numbers I’m adding together, then do the addition, then divide by the multiplier to return the numbers back to their original decimal state.

By performing the addition on integers, no rounding issues occur.

Libraries

If you’re needing precision with lots of complex calculations, there are JavaScript libraries specifically for this (although some are horrible Java ports). bignumber.js looks OK and I remember using bigint.js with @danielcassidy and @anttears back in the day.