Some people don't find these shenanigans hindering their practical work. But believe me, I avoided a production bug (which would have made my fancy looking UI go berserk) by serendipitously testing a sample dataset that unveiled yet another sly trick of JS arithmetic.
And so, finally, I decided to compile a few such tricks here in this post. Hope you have fun discovering something new.
console.log(0.1 + 0.2) console.log(0.1 + 0.2 - 0.2) console.log(0.1 + 0.7) console.log(0.2 + 0.7)
Run the above code in your developer console and be like WTF!! How can you mess up something as simple as this JS??
If you are too lazy to check for yourself, this is what the output looks like:
0.30000000000000004 0.10000000000000003 0.7999999999999999 0.8999999999999999
The reason behind this behavior is the accuracy with which JS stores float values.
I was working on a report visualization project where I had to display the total bounced email percentage by adding up soft-bounce and hard-bounce. Since this was to be displayed in a compact UI, displaying 0.30000000000000004% instead of 0.3% would make my page go insane (much to the amusement of the user). Fortunately, I realised it as soon as I tested it and fixed it.
So, how do we fix this?
let a = +(0.1 + 0.2).toFixed(1) let b = +(0.1 + 0.7).toFixed(2)
toFixed(num) converts the
string with precision of
num after decimal point. The unary operator converts the
string back to
number. If you are using this to display somewhere in your UI, you are pretty much done after 'toFixed'. If you are going to use it for further calculations, go ahead and convert it to
"0.30" in string when converted to number becomes 0.3. So, don't be surprised.
I don't see why someone would write a code like this, but let's assume you somehow landed with these set of numbers (say from an API call response) and are performing an operation as below:
console.log(022 === 018) //true console.log(023 === 019) //true console.log(010 === 008) //true //if i keep going on, you will soon see the pattern
Common, don't be lazy and give this a shot in your console. The best way to learn JS is to befriend that F12 of your browser.
Most of you would have guessed what's happening here. But let me lay it down for you either way...
When JS sees 0 in the start of a number, it converts it to Octa. That explains 022, 023, 010 (you can experiment more). But wait! 8 and 9 are not valid numbers of the Octa Number System. Well, that's why they are converted to Decimal.
And this explains 022 (18 in Decimal) even strictly matches with 018.
There is no real-world example of this crazy expression, but I loved it so much that I decided to pop it in anyways. I came across this in WTF-JS (quite apt!).
console.log((!+++!).length) // 9
Yes, the answer is 9! Whaaaaa 🤐
There was no way I was going to give up without finding out why! After a gazillion unsatisfying hypothesis, I finally made one that I am quite sure of, and here it is...
But before scrolling down for the solution, I urge you to try figuring out for yourself. Believe me, it's Merlin's Beard Satisfying!
First let's see what are we finding the length of, at first place?
console.log(!+++!) // Ans: "truefalse" //HOLY CHRIST!!!!
How on earth did JS do this??
Let's chop it down to three parts:
(!+) + () + (!)
!alone is really nothing in JS. God knows why it took me so long to figure out... And soooo,
+works as a unary operator on an empty object, which basically converts
is an empty array, its numeric value is
So this is equivalent to
true(because Boolean of 0 is TRUE).
is an empty array. Adding this with a boolean
trueconverts both of them to string. So the stringified value of
is an empty string
"". Hence, so far we have
Now, the last one might be get a little tricky considering the first one in picture and if you are not aware of falsy values in JS.
! is not the same as
 is NOT converted to number, but directly applied to
Boolean(!) which is FALSE.
There are only 8 falsy values in JS, find them here.
So all-in-all, this expression is equivalent to:
We know here on. string + boolean = string. So the result is
"truefalse". And the length of it is 9.
DAMN! This felt GOOD! 🤸♂️
I will end the list for now. But I have way too many such examples. If you liked it, let me know and I will make this into a series. Also, if you have such examples which got you like- Whaaaaaa 👀 , do share it in comment section.