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!

 
14
Kudos
 
14
Kudos

Now read this

Bitwise Operations Part 3: The Logic Operators

Check here for Part 2, Binary and Two’s Complement. In this post I’ll be covering all the logical bitwise operators in Javascript, but the principle is the same across all languages. There are so many cool and exciting things we can do... Continue →