Challenge: Cash Register- Problem with floats

Hey there, i have an issue with the Cash Register Challenge.

I marked the part in the code with a comment.
In the forEach loop i am substracting number values until claim is zero or the cidObject runs out of coins. The substracted values are stored in the change object.
It works with every test except the last one.
In the last one instead of the value 50 for Pennys i get 0.5000000000000002.
If you run the script youll see it in the console.
I hardcoded the solution–not that elegant.
Can someone help me out ? I was/am stuck on this for quiet some time.

Here is the code:



  const money ={
    "100.00": "ONE HUNDRED",
    "20.00": "TWENTY",
    "10.00": "TEN",
    "5.00": "FIVE",
    "1.00": "ONE",
    "0.25": "QUARTER",
    "0.10": "DIME",
    "0.05": "NICKEL",
    "0.01": "PENNY"
  }

  function checkCashRegister(price, cash, cid) {
    // claim
    let claim = cash-price;

    //create a currency object (change) and the cid Total
    let change = {};
    let cidTotal = 0
    cid.forEach(n=>{
      let key = n[0];
      let value = n[1];
      change[key]= 0
        cidTotal+=n[1]
      })

// create an object to substract the value from
      let cidObject ={};
      cid.forEach(n=>{
        let key = n[0];
        let value = n[1];
        cidObject[key] = value;
      })
    // get amount of curreny units
    let numbers = Object.keys(money);


//This is the problematic part:
// I am substracting from claim and cidObject, until their values are 0
// and i am storing those substracted values in the change object
    numbers.forEach(value =>{
      while (value<= claim && value <=cidObject[money[value]]){
        claim= claim.toFixed(2)-value;
        cidObject[money[value]]=cidObject[money[value]].toFixed(2)-value;
        change[money[value]]+=1*value;
      }
    })
    console.log(change)
    //hardcoded solution: to fix the float: PENNY 0.5000000000000002 => PENNY: 0.5
    change.PENNY = parseFloat(change.PENNY.toFixed(2))
    console.log(change)

}
// checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90 ], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])
// checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])
// checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])
// checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])
checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])

Thanks !

Dollar can only go down to 1/100, so you could either round values for two digits or avoid floats entirely by multiplying with 100.
Either way, the problem is computers can run into problems with floats, given how they only have integers base-2 in memory (bits) and thus what we think is a simple base-10 float might actually have infinite digits in base-2, causing calculations to approximate values and thus have tiny fractions of errors.

1 Like

What I remember if it’s would be helpful is that only:
Let say we want 20+10 cents;
We have to add two values 0.2 and 0.1, if we do it directly with JS we already know that there will be problems.

So the right way:

  1. Multiply each value by 100: (0.2 * 100 + 0.1 * 100) = 30 cents.
  2. Recover the value to money: (0.2 * 100 + 0.1 * 100) / 100 = 0.3.

Beside that, I believe there is also some libraries ready to use if you google it.

2 Likes

Interesting. Ok thanks for the quick reply. Ill figure something it out

Thanks for the quick reply. Ill have a look into some of those libraries.

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