Javascript Floating Point (im)Precision and Solution

In an exercise to re-implement Javascript’s parseFloat(), I came across a common gotcha. Go ahead, try it yourself:

``````var pointThree = 0.1 + 0.2;
console.log(pointThree === 0.3);
``````

No, your console isn’t broken. 0.1 + 0.2 == 0.30000000000000004 according to IEEE 754. And yes, all the major implementations of adhere to this rule. Safari, Firefox, Internet Explorer, and even… Chrome….? Yes, even Chrome.
Why don’t they just fix it? At the hardware level, you can’t fix it because computers calculate in binary. This will understandably return rounding errors for most decimal numbers, due to the fact that most decimal numbers can’t be represented in finite binary numbers.

“It’s a feature, not a bug” -IEEE

Veteran programmers will recognize it as Floating Point Arithmetic. New programmers, unfortunately, will come to know this as the bug that wasted your last hour. Additionally, Javascript beginners aren’t insulated against this at all. Perhaps it would have been a good idea to abstract away this “feature” in the beginning, but the foundation has already been set. Cross-compiler consistency is now more important than a quality of life change. It should be also noted that Javascript isn’t the only one, other languages like Ruby and Java will also return this. Others like Python and Go will try to abstract it away for you.

Solutions

A simple workaround is to use toPrecision() and parseFloat()

``````var pointThree = 0.1 + 0.2;
console.log(parseFloat(pointThree.toFixed(5)));
//returns 3
``````

`toFixed()` will round the number to the specified length and return it as a string, which will be passed into `parseFloat()` to be converted back into a number. This should solve most errors average programers would run across. For a more robust solution, consider importing libraries like bignumber.js into your code.

What about `toPrecision()`?

It works just as well, except one small difference.
`toFixed(n)` will return a string of total length n, while `toPrecision(n)` will return a string of length n after the decimal. So in most cases it’s better to leave the whole numbers untouched.

Best of luck, everyone!

How to Efficiently Merge Two Lists Unix Timestamps

Say you’re retrieving a comprehensive list of someone’s Github activities, and you now have data of each week’s additions, deletions, and commits. Great! We can just chart it out, nice and easy. Now, say someone comes in and asks to... Continue →