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.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.