Cash register - all tests outside fcc not working

Hey, here is my solution. I am sure it is not perfect but I just wanted to point out that if you were to test different numbers (such as the test I did below), the solution that is shown here would output something incorrect. It is due to float imprecision. I spend some time on this problem so I was unhappy when it didn’t work in all cases. Just so you know.


function checkCashRegister(price, cash, cid) {
// first block until if calculates total in cid and if its same as change due it returns closed
let changeDue = (cash - price).toPrecision(7);
let total = 0;
let valueOfCurrency = [0.01, 0.05, 0.1, 0.25, 1, 5, 10, 20, 100];
let finalArr = [];
console.log(changeDue)

for(let i = 0; i < cid.length; i++){
 for(let j = 1; j < cid[i].length; j++){
   total += cid[i][j];
 }
}
if(changeDue == total){
 return {status: "CLOSED", change: cid};
 }
else if(total < changeDue){
 return {status: "INSUFFICIENT_FUNDS", change: []};
}

else if(total > changeDue){
 for(let i = cid.length - 1; i >= 0; i--){
  for(let j = 1; j < cid[i].length; j++){
    if(changeDue/valueOfCurrency[i]===1 && changeDue > 0){
      finalArr.push(cid[i][0], valueOfCurrency[i]);
      changeDue = changeDue - valueOfCurrency[i];
    }
    else if(changeDue/valueOfCurrency[i] > 1 && changeDue > 0){
      if(cid[i][1]/valueOfCurrency[i] > changeDue/valueOfCurrency[i]){
        finalArr.push([cid[i][0], Math.floor(changeDue/valueOfCurrency[i])*valueOfCurrency[i]]);
        changeDue = (changeDue - Math.floor(changeDue/valueOfCurrency[i])*valueOfCurrency[i]).toPrecision(7);
      }
      else{
         finalArr.push([cid[i][0], cid[i][j]]);
         changeDue = changeDue - cid[i][j];
      }
      
    }
    
  }
  
}
 if(changeDue==0){
   return {status: "OPEN", change: finalArr};
 }
 else{
   return {status: "INSUFFICIENT_FUNDS", change: []};
 }

}
}

console.log(checkCashRegister(18.99, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["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/90.0.4430.85 Safari/537.36.

Challenge: Cash Register

Link to the challenge:

Handling floating point roundoff is part of the challenge. Personally, I prefer to convert everything to an integer number of cents before doing the calculations.

I am certainly not complaining, it´s just that I found out that the floating point imprecision is not considered in the official solution, so if someone wondered why some edge cases don´t work I thought it could help them, if they knew what causes the issue. From what I´ve read, banking systems often use a library that deals with this problem.

It seems to be covered in the ‘official’ solution(really, I don’t know why we have a solution posted)

      // Round change to the nearest hundreth deals with precision errors

Why such a hostile tone? It is mentioned in the solution but it doesn’t actually work for the edge case I have in my solution. I tried it in several compilers. Is there something I have missed?

Yours does not appear to be a direct copy-paste of the ‘official’ solution. Really, there is no ‘official’ solution, which is why it is in quotes. No hostile tone is intended by the quotes, it’s just reflecting the fact that there is no official solution. The ‘guide’ solution, which is what I assume you mean by ‘official’ does have logic to handle floating point roundoff.

I generally just recommend that people convert their drawer to an integer number of cents before doing anything as to avoid the issue altogether.

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