Introduction
Wrapping up the freeCodeCamp metric-imperial converter project, I discovered a strange bug. A possible user input is a fractional number w/unit such as 3/4mi
. However, there is a possibility a user could input 3/0mi
. Decided to test this out in the console and got the following:
3/0
// Infinity
I was expecting an error but got the value Infinity
. Let's explore this to see if we can find out why.
Explore
First, I went to MDN to see if that was the expected result:
2.0 / 0 // Infinity
2.0 / 0.0 // Infinity, because 0.0 === 0
2.0 / -0.0 // -Infinity
It looks to be the expected answer, but I noticed something. Dividing by a negative zero results in a negative Infinity. Not sure what that means, I decided to check the ECMAScript.
NOTE: ECMAScript is the official specification of JavaScript.
According to the ECMAScript:
The result is determined by the specification of IEEE 754-2019 arithmetic
...
Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule already stated above
Unfortunately, I do not have access to IEEE documents. So my journey ends here. However, here are some lecture notes, see pg 10 I found about the subject.
Solution
At first I tried a try/catch
solution:
var [numerator, denominator] = num.split('/');
try {
// The plus converts a string to a number
result = +(numerator) / +(denominator);
} catch(e) {
throw new RangeError('Cannot divide by zero');
}
// Infinity
As expected we get Infinity
. Searching MDN I found a useful method [isFinite]:(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
The global isFinite() function determines whether the passed value is a finite number. If needed, the parameter is first converted to a number.
I used that to come up with my final solution:
if (isFinite(result)) {
return result;
}
return 'Cannot divide by zero';
Of course, a user could input Infinity/Infinity
but we'll save that for another time.
Final Thoughts
It was interesting that an error would not result from dividing by zero. According to the IEEE specification, which the ECMAScript implements, it follows the rules. Something to look out for on your coding journey. The results you expect might not be so clear.
Resources
MDN - Division(/)
ECMAScript 6.1.6.1.5
MDN - isFinite
Image is Lina from Dota 2
Top comments (1)
For those interested Eddie Woo has a really good video explanation on why Divide by Zero doesn't equal infinity