Unusual behavior when adding and subtracding - Cash Register

Challenge: JavaScript Algorithms and Data Structures Projects - Cash Register

Link to the challenge:

So, I want to know why when I return the change left to be count its return 0.009999999999999691 and not plain 0 as it should be. I need it to be 0 so the rest of my solution works. I did try it whit .toFixed() and .round() to make it 0, but “change === 0” isn’t true.

function checkCashRegister(price, cash, cid) {
  let change = cash - price
//Stores the change in the exact amount of currrecy
  let changeArr = [["PENNY", 0], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]
//Function where I pass the value of the currency and the position where said currency is stored and goes
  const changeFunc = (num, index) => {
//If the change left is greater than the value of the currency and there is money left from the drawer
    while(change >= num && cid[index][1] >= num){
//Add the change to its position in the array, substrac it from the drawer and from the change left
      changeArr[index][1] += num
      cid[index][1] -= num
      change -= num
    }
  }

  changeFunc(100, 8)
  changeFunc(20, 7)
  changeFunc(10, 6)
  changeFunc(5, 5) 
  changeFunc(1, 4)
  changeFunc(0.25, 3)
  changeFunc(0.1, 2)
  changeFunc(0.05, 1)
  changeFunc(0.01, 0)

//The change left to be count. It should be 0, not 0.009999999999999691
 return change 

/* Rest of the code
  if(change !== 0) {
    return {
      status: "INSUFFICIENT_FUNDS", 
      change: []
    }
  }
  if(cid.every(elem => elem[1] === 0)){
    return {
      status: "CLOSED",
      change: changeArr
    }
  }
  if(!cid.every(elem => elem[1] === 0)){
    return {
      status: "OPEN",
      change: changeArr.filter(elem => elem[1] > 0)
                       .sort((a, b) => a[1] - b[1])
                       .reverse()
    }
  }
*/
}
console.log(checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]))

There is a well known issue with math with floating point numbers.

In base 10, any fraction with a denominator that is a multiple of only 2s and 5s can be represented perfectly - nothing else will. Try to accurately represent 1/3 or 1/5 or 1/127 in a decimal - it can’t be done.

In base 2, any fraction with a denominator that is a multiple of only 2s (exponent of 2) can be represented perfectly. Nothing else can. Type .1 + .2 into your console. That is 1/10 and 1/5 - the computer cannot accurately represent those without an infinite number of digits so they are approximations.

To fix this, you either need to use a library to handle these, do some intelligent rounding, or convert everything to cents so you can deal with integers.

In this project I used :

    change = change.toFixed(2);
    cidValue = cidValue.toFixed(2);

so later “change == 0 && cidValue == 0” worked.

That can work. That is an effective way to round the numbers and eliminate rounding error. The issue that I have is that now your “number” is a string. That is why you have to use == instead of ===. Firstly, you should almost always use === - in 5 years as a professional JS programmer, I don’t think I’ve once used == or !=. And just in general, you should be stricter when thinking about types. Almost always, a variable should be one type and not change. In many languages, this is strictly enforced.