Cash Register - program running my code is BUGGED

Tell us what’s happening:
I was able to get my code to pass the test, so I’m finished with this exercise. However, I would like to report a bug with the test.

For some mysterious reason, every time my code updates the money values, the value returned is off by a minuscule amount (~0.00000000001). My code is definitely not doing this. It is the program running the code or my computer.

This bug adversely affected my code, causing it to fail some of the test values. I was able to fix this bug by inserting an “if” statement to check if every value is a multiple of a penny value (0.01). If not, then round to the nearest penny.

This just goes to show that debugging isn’t just fixing the errors in your own code. The machine running the code could, itself, be causing problems. Phew! What a journey!

Your code so far


function checkCashRegister(price, cash, cid) {
  var change = [["PENNY", 0], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];
  var owing = cash - price;
  //console.log("owing calculated to be " + owing);
  //console.log("cid array check before loop: " + cid[8][0]);
  for (let i = cid.length - 1; i>=0; i--){
    //console.log("entered for loop at index" + i);
    let unitValue = (()=> {
      //console.log("entered immediately invoked function");
      //console.log("loop index check: " + i);
      //console.log("cid array check inside immediately invoked function: "  + cid[i][0]);
      switch(cid[i][0]){
        case "ONE HUNDRED":
          //console.log("$100 bill case checked");
          return 100;
          break;
        case "TWENTY":
          return 20;
          break;
        case "TEN":
          return 10;
          break;
        case "FIVE":
          return 5;
          break;
        case "ONE":
          return 1;
          break;
        case "QUARTER":
          return 0.25;
          break;
        case "DIME":
          return 0.1;
          break;
        case "NICKEL":
          return 0.05;
          break;
        case "PENNY":
          return 0.01;
          break;
      }
    })();
    //console.log(unitValue);
    while (owing>=unitValue && cid[i][1]!==0){
      owing -= unitValue;
      cid[i][1] -= unitValue;
      change[i][1] += unitValue;  
      //console.log("tracking owing: " + owing);
      //There's a bug, not in my code, but in the program running my code that mysteriously
      //subtracts 0.0000000000000005 or so, so I must fix this with the 'if' statement below
      if (owing%0.01!==0){
        owing = Math.round(owing*100)/100;
      }
      if (change[i][1]%0.01 !== 0){
        change[i][1] = Math.round(change[i][1]*100)/100;
      }
      if (cid[i][1]%0.01 !== 0){
        cid[i][1] = Math.round(cid[i][1]*100)/100;
      }
    }   
  }
  if (owing > 0){
    return {status: "INSUFFICIENT_FUNDS", change: []};
  } else if (cid.every((x) => (x[1] == 0))){
    return {status: "CLOSED", change : change};
  } else {  
    return {status: "OPEN", change: change.filter(x=>x[1]!==0).reverse()};
  }
} 



// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]

let array = checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]);

console.log(array["change"]);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36.

Link to the challenge:

“The program running your code” is, in fact, javascript within your browser. And yes, it’s bugged. It happens in floating point math - as soon as you leave the land of nice, clean integers, numbers can get a little hinky.

The Math.round() trick is commonly used, as is Number.toFixed(precision); - rounding will bring it to an integer, and you can then divide by 100 to get two decimal places, as you do. Using .toFixed() does work, but presents its own issues - the value returned is no longer a number, but a string.

This is a fairly common gotcha with javascript, floating point weirdness is sort of a thing.

1 Like