Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

I haven’t completed this challenge yet, but I’m stuck with a problem. So far it seems fine, CID is getting deducted everytime you hit “Purchase”. But on the third repeat press, the CID would randomly display lots of decimal points. Can anyone explain why is it behaving this way? Thank you!

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="styles.css" />
        <title>Document</title>
        <meta name="description" content="This will be shown in search engines.">
    </head>
    <body>
        <div>
          <p>Cash:</p>
          <input id="cash" type="number">
        </div>

        <button id="purchase-btn">Purchase</button>
        
        <p>Change due:</p>
        <div id="change-due">
        </div>

        <div id="cid"></div>
        
        <script src="script.js"></script>
    </body>
</html>
/* file: script.js */
const cash = document.getElementById('cash');
const purBtn = document.getElementById('purchase-btn');
const change = document.getElementById('change-due');
const divCID = document.getElementById('cid');

let price = 1.87;
cash.value = 2

let cid = [
  ['PENNY', 1.01],
  ['NICKEL', 2.05],
  ['DIME', 3.1],
  ['QUARTER', 4.25],
  ['ONE', 90],
  ['FIVE', 55],
  ['TEN', 20],
  ['TWENTY', 60],
  ['ONE HUNDRED', 100]
];

const currUnits = {
  'PENNY': 0.01,
  'NICKEL': 0.05,
  'DIME': 0.1,
  'QUARTER': 0.25,
  'ONE': 1,
  'FIVE': 5,
  'TEN': 10,
  'TWENTY': 20,
  'ONE HUNDRED': 100,
}

function displayCID(){
  divCID.innerHTML = '';
  cid.forEach(coinNote => {
  divCID.innerHTML += `<p>${coinNote[0]}: $${coinNote[1]}</p>`
})
}

displayCID();

purBtn.addEventListener('click', () => {
  const cashInCents = cash.value * 100;
  if(cashInCents < price * 100){
    console.log('cashInCents < price', cashInCents);
    alert("Customer does not have enough money to purchase the item")
  }else if(cashInCents === price * 100){
    console.log('cashInCents === price');
    change.textContent = "No change due - customer paid with exact cash";
  }else if(cashInCents > price * 100){
    let remaining = cashInCents - price * 100;
    console.log('cashInCents > price', `remaining: ${remaining}p`);

    change.innerHTML = '';
    for (let i = cid.length - 1; i >= 0; i--){
      const coinValInCents = currUnits[cid[i][0]]*100
      if(remaining >= coinValInCents){
        // console.log((remaining - remaining % coinValInCents)/coinValInCents);
        const numOfCoins = (remaining - remaining % coinValInCents)/coinValInCents

        change.innerHTML += `<p>${numOfCoins} x ${cid[i][0]}</p>`;

        cid[i][1] = parseFloat(cid[i][1]) - (numOfCoins * currUnits[cid[i][0]]);
        remaining = remaining % coinValInCents;
        // console.log(`coin: ${cid[i][0]}; value: ${currUnits[cid[i][0]]}; num: ${numOfCoins}; total value: ${(numOfCoins * currUnits[cid[i][0]])}`);
      };
      displayCID();
    }
    /*
    for (let i = cid.length - 1; i >= 0; i--){
        if(remaining - currUnits[cid[i][0]] > 0){
          while(remaining > currUnits[cid[i][0]] && cid[i][1] > 0){
            remaining -= currUnits[cid[i][0]];
            cid[i][1] -= currUnits[cid[i][0]];
            change.innerHTML += `<p>${currUnits[cid[i][0]]}</p>`
          }
        }
    }
    divCID.innerHTML = '';
    cid.forEach(coinNote => {
      divCID.innerHTML += `<p>${coinNote[0]}: $${coinNote[1]}</p>`
    })
    */
  }
})
/* file: styles.css */
#cid{
  border: solid 1px black,
}

Your browser information:

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

Challenge Information:

Build a Cash Register Project - Build a Cash Register

What you are seeing is a so-called floating-point error. Representing float numbers accurately is hard for computers and any kind calculation on floats can introduce imprecision. For example:

console.log(0.1 + 0.1 + 0.1 == 0.3)  // false

Thanks for the insight. I have tried adding parseInt() almost everywhere after converting price into cents. But after a few times of triggering the function, a random 0.01 was deducted from the “Dime”, which should only be deducted 0.10 at a time. How do I prevent this? Thanks!

Could you share updated code?

Not sure if I’m supposed to post the fully working codes here, but I’ve replaced all the parseInt() with Math.round(), which seems to round the numbers into whole numbers before storing back into the array.

Well… but you were saying that it was not working correctly?