JavaScript: Cash Register - 6th test

Dear FreeCodeCampers,

I am not able pass 6th test in this challenge. Here is my code:

function checkCashRegister(price, cash, cid) {
  var finalOutput = {status: null, change: []};
  var change = (cash-price).toFixed(2);
  var denom = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];
  var currency = [];
  var cidAmount = [];
  var numBills = [];
  var myarr1 = [];
  var myarr2 = [];
  var finalArr = [];
  var output = [];
  var outputVal = 0;
  var mynum1 = 0;
  var mynum2 = 0;
  var rem1 = 0;
  var rem2 = 0;

  // fill currency and cidAmount arrays
  for(var i=cid.length-1; i>=0; i--){
    currency.push(cid[i][0]);
    cidAmount.push(cid[i][1]);
  }

  // fill numBills array
  for(var i=0; i<currency.length; i++){
    numBills.push(Math.round(cidAmount[i]/denom[i]));
  }

  // total the cash in the register
  var cid_amt = cidAmount.reduce(function(a,b){
    return a + b;
  },0);
  cid_amt = cid_amt.toFixed(2);

  // handle insufficient funds
  if(cid_amt < change){
    finalOutput.status = "INSUFFICIENT_FUNDS";
    finalOutput.change = [];
  }

  // handle exact change
  if(cid_amt === change){
    finalOutput.status = "CLOSED";
    finalOutput.change = cid;
  }

  // Separate change into its integer and decimal parts
  var changeInt = Math.floor(change);
  var changeDec = Number((change%1).toFixed(2));

  // handle a transaction of integer portion of change
  if(cid_amt >= changeInt){
    for(var j=0; j<5; j++){
      if(denom[j] > changeInt){
        continue;
      }

      if(Math.floor(changeInt/denom[j]) > numBills[j]){
        mynum1 = numBills[j];
        for(var k=0; k<mynum1; k++){
          changeInt = changeInt - denom[j];
          rem1 = rem1 + denom[j];

        }

      }
      else if(Math.floor(changeInt/denom[j]) <= numBills[j]){
        mynum1 = Math.floor(changeInt/denom[j]);
        for(var k=0; k<mynum1; k++){
          changeInt = changeInt - denom[j];
          rem1 = rem1 + denom[j];
        }

      }
      myarr1.push(currency[j], rem1);
      rem1 = 0;
    }
  }
  // handle a transaction of decimal portion of change
  if(cid_amt >= changeDec){
    for(var j=5; j<9; j++){
      if(denom[j] > changeDec){
        continue;
      }

      if(Math.floor(changeDec/denom[j]) > numBills[j]){
        mynum2 = numBills[j];
        for(var k=0; k<mynum2; k++){
          changeDec = (changeDec - denom[j]).toFixed(2);
          rem2 = rem2 + denom[j];
                
        }
         
      }
      else if(Math.floor(changeDec/denom[j]) <= numBills[j]){
        mynum2 = Math.floor(changeDec/denom[j]);
        for(var k=0; k<mynum2; k++){
          changeDec = (changeDec - denom[j]).toFixed(2);
          rem2 = rem2 + denom[j];
          
        }
        
      }
      
      myarr2.push(currency[j], rem2);
      rem2 = 0;
    }
  }
  finalArr = myarr1.concat(myarr2);
  for(i=0; i<finalArr.length; i +=2){
    output.push(finalArr.slice(i,i+2))
  }

  for(i=0; i<output.length; i++){
    outputVal = outputVal + output[i][1]; 
  }

  outputVal = outputVal.toFixed(2);
  // handle transaction
  finalOutput.status = "OPEN";
  finalOutput.change = output;
  if(outputVal < change){
    finalOutput.status = "INSUFFICIENT_FUNDS";
    finalOutput.change = [];
  }

  return finalOutput;

}



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

OUTPUT:
=> { status: ‘OPEN’,
change:
[ [ ‘QUARTER’, 0 ],
[ ‘DIME’, 0 ],
[ ‘NICKEL’, 0 ],
[ ‘PENNY’, 0.5000000000000002 ] ] }

PENNY shows recurring decimals, this is causing the issue. Please guide me on how to fix this.

Thank you!

Javascript is known for its floating point errors. You can search on google for ways to mitigate this.

I believe I had to to something along the lines of Number.parseFloat().toFixed(). I’ll let you figure out how to use those functions (via MDN or something). Or heck, you can probably forget Number.parseFloat() and just do a toFixed() after all the calculations. Should work.

Thank you @zapcannon99. I tried toFixed() but it didn’t resolve the issue. Let me try Number.parseFloat().toFixed() and get back.

Did you add the correct arguments? I left the arguments out on purpose in an attempt to force you to search up the function on your preferred search engine.

Yes, I added the correct arguments.

Ok. And did you do after the calculations for penny?

Maybe toFixed on this line?

Actually, this case should not go into calculation section as amount in the cash register and the change are equal, the below condition should be satisfied and it should return CLOSED and cid.

  // handle exact change
  if(cid_amt === change){
    finalOutput.status = "CLOSED";
    finalOutput.change = cid;
  }

I used toFixed(2) on both cid_amt and change.

@zapcannon99 - I did a toPrecision() on rem2.

rem2 = Number((rem2 + denom[j]).toPrecision(2));

This solved the floating point error but missing the change === cashInRegister codition.

OUTPUT:

CashInRegister: 0.5
Change: 0.5
=> { status: ‘OPEN’,
change:
[ [ ‘QUARTER’, 0 ],
[ ‘DIME’, 0 ],
[ ‘NICKEL’, 0 ],
[ ‘PENNY’, 0.5 ] ] }

I’d rather go for toFixed because what if you have more than 100 pennies. Not realistic, but toPrecision would fail in those cases. toFixed() looks at only the decimal places.