Today we are doing a little debugging and dealing with decimals in JavaScript.
Disclaimer: There are MANY ways to solve this problem this is an answer that I would see or use in a coding interview and would accept as a proper answer
TLDR: Solution is at the bottom of the post
The Problem
Fix this function:
function addAndCheckEqual(num1, num2, num3){
return num1 + num2 === num3
}
Tests:
areEqual(1, 2, 3) //true
areEqual(11, 12, 13) //false
areEqual(10, 10, 20) //true
areEqual(.1, .2, .3) //true
areEqual(1.1, 1.2, 1.3) //false
areEqual(1.1, 1.2, 2.3) //true
Solution
We need to create a function that accepts 3 numbers.
const addAndCheckEqual = (num1, num2, num3) => {
}
The answer you may find a lot will use Math.abs (to get the absolute value of the number) and Number.EPSILON. Number.EPSILON is just the, “smallest possible "increment" you can represent with that particular floating point type” (from the article referenced below).
const addAndCheckEqual = (num1, num2, num3) => {
return Math.abs((num1 + num2) - num3) < Number.EPSILON;
}
The answer above will run into times that it will give the wrong results. For example: addAndCheckEqual(10000001.1, 0.2, 10000001.3) will return false when it should return true.
The only way to really make sure you are getting the correct response you need to set your own tolerance. If you want to go to .001 and that is a close enough comparison for you then use that. There is a really great article that dives deeply into why Number.EPSILON doesn’t always work and what a good tolerance to set is, here. But at the end of the day a good tolerance depends on how accurate your numbers have to be. An example of how to set your own tolerance would be this:
const addAndCheckEqual = (num1, num2, num3) => {
return Math.abs((num1 + num2) - num3) < .000000001
}
I hope you had fun with this one! Please leave your repo links to your form in the comments section. Also let me know if you like the multi day challenges or really hate them! If you have any challenge you would like to see done also leave that in the comments below you may see it come up! If you would like to get the challenge emailed to you every day in morning and a notification when the solution is posted subscribe here.
Top comments (1)
The problem here is that all numbers in JS are IEEE 754 64 bit numbers (1 bit sign, 11 bit exponent, 52 bit mantissa). Allowing for imprecision will solve the false negative, but will increase the chance of false positives at the same time.
A better solution would be to go beyond this number format and use something like big.js instead.