Cash Register - Value changing from 0.01 to 0.0099999...?

Here is a link to my code: https://codepen.io/pmnord/pen/QWLPjQv?editors=0012

My issue should be well logged to the console for you to see. It appears that as I reach the final penny needed to remove from the changeOwed variable, the value goes from being 0.01 to 0.009999999999994869. Thus breaking my code. Is this right? Why is this happening? What’s the best way to fix this? Thanks.

JavaScript Algorithms and Data Structures Projects: Cash Register

Well I got it to pass all the tests by just removing that test for strict equality between changeGiven and changeOwed. This is what I got FCC to accept:

function checkCashRegister(price, cash, cid) {
  
  let changeOwed = (cash - price);
  console.log("change owed " + changeOwed)
  const cidTotal = cid.reduce((acc, el) => acc + el[1], 0).toFixed(2);//.toFixed(2);
  console.log("total in drawer " + cidTotal)

  // Set up drawer object
  const drawer = cid.reduce((acc, el, arr) => {
    acc[el[0]] = el[1];
    return acc;
  }, {})
  console.table(drawer)

  // Handle simple cases
  if (changeOwed > cidTotal){
    return {status: "INSUFFICIENT_FUNDS", change: []};
  }
  else if (changeOwed.toFixed(2) === cidTotal) {
    return {status: "CLOSED", change: cid};
  }

  // Handle complex change calculation
  const values = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.10,
    "QUARTER": 0.25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20,
    "ONE HUNDRED": 100
  }

  const changeGiven = {};

  for (let i = (Object.keys(drawer).length - 1); i >= 0; i--) {
    let bill = Object.keys(drawer)[i];
    let amount = values[bill];

    while (changeOwed.toFixed(2) - amount >= 0 && drawer[bill] >= amount) {
      drawer[bill] -= amount;
      changeGiven[bill] = changeGiven[bill] + amount || amount;
      changeOwed -= amount;
    }
  }

  // REPLACED BELOW
  // if (Object.values(changeGiven).reduce((acc, el) => acc + el, 0).toFixed(2) !== cash - price) {
  //   console.log("Total changeGiven " + Object.values(changeGiven).reduce((acc, el) => acc + el, 0).toFixed(2));
  //   console.log("original changeOwed value: " + (cash - price));
  //   console.log("changeOwed is now " + changeOwed);
  //   return {status: "INSUFFICIENT_FUNDS", change: []};
  // }

  if (changeOwed.toFixed(2) > 0) {
    return {status: "INSUFFICIENT_FUNDS", change: []};
  }

  return {status: "OPEN", change: Object.entries(changeGiven)}

}

Floating point math is only as precise as the number of bits allocated allows (64 bits in javascript). So you get some rounding that looks like this. You will want to apply the method toFixed(2) to make the output fixed to include 2 digits after the decimal point. No more, no less. petern’s example uses this.

1 Like

I multiplied all the numbers by 100 so I was working in cents and then used Round().

Then I divided by 100 when adding to the final array.