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!

 
19
Kudos
 
19
Kudos

Now read this

Bitwise Operations Part 1: A Quick Introduction to Bases

In this series, I will touch on the fundamentals of understanding binary and learning to reason with it, then how we can use it in Javascript. What is decimal notation, really? # We learn to count in decimals, or base 10. What this means... Continue →