Cash register challenge -- rounding error

This is the only test that fails. My pennies are coming up one short. In debugging I see it’s because when the value for change should be .01 it is something like .009… . How do I avoid this rounding error? And why does it happen only with pennies?

function checkCashRegister(price, cash, cid) {
  let dict = new Map(
    [
      ["PENNY", .01],
      ["NICKEL", .05],
      ["DIME", .1],
      ["QUARTER", .25],
      ["ONE", 1],
      ["FIVE", 5],
      ["TEN", 10],
      ["TWENTY", 20],
      ["ONE HUNDRED", 100]
    ]);
  let amountInDrawer = 0;
  let change = cash - price;
  change = Math.round(change*100)/100;
  
  let obj = {};
  for (let i = 0; i < cid.length; i++) {
    amountInDrawer += Number(cid[i][1]);
  }
  if (change > amountInDrawer) {
    obj.status = "INSUFFICIENT_FUNDS";
    obj.change = [];
  }
  else if (change === amountInDrawer) {
    obj.status = "CLOSED";
    obj.change = cid;
  }
  else {
    let changeArray = [];
    for (let i = cid.length - 1; i >= 0; i--) {
      if (dict.get((cid[i][0])) > change) {
        continue;
      }
      let value = dict.get(cid[i][0]);
      let temp = 0;
      while (temp < Number(cid[i][1])) {
        if (value > change) {
          break;
        }
        change -= value;
        temp += value;
      }
      if (temp === 0) {
        return { status: "INSUFFICIENT FUNDS", change: [] };
      }
      changeArray.push([cid[i][0], temp]);
    }
    obj.status = "OPEN";
    obj.change = changeArray;
  }
  return obj;
}

console.log(checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]));

Link to the challenge:

This comes from the fact that computers are very stupid and cannot store decimals accurately.

In this case, my suggestion is to work with whole numbers. Instead of storing your values as dollars, with cents represented as a decimal, I suggest multiplying your numbers by 100 (so a quarter is 25, for example), working with those, and then dividing by 100 for your output.

1 Like

This video is on this subject

Instead of doing that I just rounded and divided every time I updated the change variable, and that got rid of the errors.

function checkCashRegister(price, cash, cid) {
  let dict = new Map(
    [
      ["PENNY", .01],
      ["NICKEL", .05],
      ["DIME", .1],
      ["QUARTER", .25],
      ["ONE", 1],
      ["FIVE", 5],
      ["TEN", 10],
      ["TWENTY", 20],
      ["ONE HUNDRED", 100]
    ]);
  let amountInDrawer = 0;
  let change = cash - price;


  let obj = {};
  for (let i = 0; i < cid.length; i++) {
    amountInDrawer += Number(cid[i][1]);
  }
  amountInDrawer = Math.round(amountInDrawer * 100) / 100;
  if (change > amountInDrawer) {
    obj.status = "INSUFFICIENT_FUNDS";
    obj.change = [];
  }
  else if (change === amountInDrawer) {
    obj.status = "CLOSED";
    obj.change = cid;
  }
  else {
    let changeArray = [];
    for (let i = cid.length - 1; i >= 0; i--) {
      if (dict.get((cid[i][0])) > change) {
        continue;
      }
      let value = dict.get(cid[i][0]);
      let temp = 0;
      while (temp < Number(cid[i][1])) {
        if (value > change) {
          break;
        }
        change -= value;
        **change = Math.round(change * 100) / 100;**

        temp += value;
      }
      if (temp === 0) {
        return { status: "INSUFFICIENT_FUNDS", change: [] };
      }
      changeArray.push([cid[i][0], temp]);
    }
    obj.status = "OPEN";
    obj.change = changeArray;
  }
  return obj;
}
1 Like

That’ll work too. Good job working through it! Happy coding.

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