Cash Register problem with floating point numbers before any changes are made

Tell us what’s happening:
I’ve been having weird rounding problems with this challenge, I know there are floating point issues with division, but I’m not doing any division except to remediate the problems that are already occurring. I stuck in a few rounding functions to fix some of the problems I was having, but I still couldn’t get the last closed one to work correctly so I console.logged it and noticed my pennies section was off at the end. Then I console.log(cid) right at the beginning before I ever did anything to anything and it’s giving me this:

(2) ["ONE HUNDRED", 0]
(2) ["TWENTY", 0]
(2) ["TEN", 0]
(2) ["FIVE", 0]
(2) ["ONE", 0]
(2) ["QUARTER", 0]
(2) ["DIME", 0]
(2) ["NICKEL", 0]
(2) ["PENNY", 0.009999999999999691]

How is that even possible? The cid I passed in was

[["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]

So I don’t understand how it converted to some crazy number before I even did anything with it? And how did it mostly work if there was barely even a penny in there according to my log?

Your code so far


function checkCashRegister(price, cash, cid) {
  const value = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.10,
    "QUARTER": 0.25,
    "ONE": 1.00,
    "FIVE": 5.00,
    "TEN": 10.00,
    "TWENTY": 20.00,
    "ONE HUNDRED": 100.00
  };
  console.log(cid);
  cid.reverse();

  var rawChange = cash - price;
  var remaining = rawChange;

  var changeObj = {
    status: '',
    change: []
  };

  var j = 0;
  let cidCopy = cid;
  cidCopy.forEach(x => {
    if(value[x[0]] < rawChange && remaining > 0 && remaining > value[x[0]]) {
      changeObj.change.push([x[0], 0])
      changeObj.status = "OPEN";
      while (remaining - value[x[0]] >= 0 && x[1] - value[x[0]] >= 0) {
        x[1] = x[1] - value[x[0]];
        remaining -= value[x[0]];
        remaining = Math.round(remaining*100)/100;
        changeObj.change[j][1] += value[x[0]];
      }
      j += 1;
    }
  });

  if (remaining > 0.01) {
    changeObj.status = 'INSUFFICIENT_FUNDS';
    changeObj.change = [];
  } else if (cid.every(x => {return x[1] < .01;})) {
    changeObj.status = 'CLOSED';
    changeObj.change = cid;
  } 

  console.log(changeObj);
  return changeObj;
}

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

Your browser information:

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

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register

Note if I take all the code out and just do console.log(cid), it looks fine, so something in here is messed up but I can’t figure out for the life of me what it is.

Also, I just tried slicing CID instead of how I copied it originally, but no matter what I do, if I console.log(cid), it always shows 0 pennies even though I never modified CID

Got it all taken care of had to add in a couple unary’s and fixed my cidCopy by stringifying it.

function checkCashRegister(price, cash, cid) {
  var cidCopy = JSON.parse(JSON.stringify(cid))
  cidCopy.reverse();
  
  const value = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.10,
    "QUARTER": 0.25,
    "ONE": 1.00,
    "FIVE": 5.00,
    "TEN": 10.00,
    "TWENTY": 20.00,
    "ONE HUNDRED": 100.00
  };

  var rawChange = cash - price;
  var remaining = rawChange;

  var changeObj = {
    status: '',
    change: []
  };

  var j = 0;

  cidCopy.forEach(x => {
    x[1] = parseFloat(x[1]);
    if(value[x[0]] < rawChange && remaining > 0 && remaining > value[x[0]]) {
      changeObj.change.push([x[0], 0])
      changeObj.status = "OPEN";
      while (remaining - value[x[0]] >= 0 && x[1] - value[x[0]] >= 0) {
        x[1] = (x[1] - value[x[0]]).toFixed(2);
        remaining = (remaining - value[x[0]]).toFixed(2);
        changeObj.change[j][1] = +(+changeObj.change[j][1] + value[x[0]]).toFixed(2);
      }
      j += 1;
    }
  });

  if (remaining > 0.01) {
    changeObj.status = 'INSUFFICIENT_FUNDS';
    changeObj.change = [];
  } else if (cidCopy.every(x => {return x[1] < .01;})) {
    changeObj.status = 'CLOSED';
    changeObj.change = cid;
  } 

  console.log(changeObj);
  return changeObj;
}

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