Cash resigter project floating point issue

Tell us what’s happening:
My code produces the value of penny as 0.03 but it should do 0.04 instead, I have no idea where did I go wrong also this isn’t finished code.

Your code so far


function checkCashRegister(price, cash, cid) {

  // Store the currency unit and amount for ease
  let currencyUnit = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.1,
    "QUARTER": 0.25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20,
    "ONE HUNDRED": 100,
  }

  let result = {}
  let changes = [];
  let change = cash - price;
  let sufficient = false; // Sum of value of changes equal to change

  for(let i = cid.length - 1; i >= 0; i--) {
    
    if(currencyUnit[cid[i][0]] <= change && !sufficient) {
      // If the change in drawer can be equally divided

      if(change % currencyUnit[cid[i][0]] == 0) {
        let divide = change / currencyUnit[cid[i][0]];
        let sub = cid[i][1] - currencyUnit[cid[i][0]]*divide
        if (sub >= 0) {
         changes.push([cid[i][0], change])
        }

      } else {

        let divide = Math.floor(change / currencyUnit[cid[i][0]]);
        let unitChange = currencyUnit[cid[i][0]]*divide;
        let sub = cid[i][1] - unitChange;

        if (sub < 0) {
          changes.push([cid[i][0], cid[i][1]]);
          change -= cid[i][1];
        } else {
          changes.push([cid[i][0],unitChange])
          change -= unitChange;
        }
      }
    }

    let sum = 0;
    for (let i in changes) {
      sum += changes[i][1];
    }
    if(sum == change) {
      sufficient = true;
    }
  }

  if (changes.length != 0) {
    console.log({
      status:"OPEN",
      change:changes,
    });
    return {
      status:"OPEN",
      change:changes,
    }
  }
  
  return result;
}

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]])

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36.

Challenge: Cash Register

Link to the challenge:

What you encountered is exactly one of the things this project is teaching. Issue is that making calculations on float numbers is imprecise and results from it are unexpected. Due to this imprecision at the point when in change should be left one penny (0.01), change actually contain a value slightly smaller than that.

It might be easier to get your head around it when having specific example before an eyes. For that add the below somewhere after line 52, and see how both values (and especially change) are after each currency.
console.log(sum, change);

Thanks! Sorry for the late reply Internet got temporarly blocked in my area but now my code is working and I have completed the challange.

function checkCashRegister(price, cash, cid) {

  // Store the currency unit and amount for ease`
  let currencyUnit = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.1,
    "QUARTER": 0.25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20,
    "ONE HUNDRED": 100,
  }

  let result = {}
  let changes = [];
  let change = cash - price;
  let sufficient = false; // Sum of value of changes equal to change
  let ch = change;
  for(let i = cid.length - 1; i >= 0; i--) {
    
    if(currencyUnit[cid[i][0]] <= change && !sufficient) {
      // If the change in drawer can be equally divided

      if(change % currencyUnit[cid[i][0]] == 0) {
        let divide = change / currencyUnit[cid[i][0]];
        let sub = cid[i][1] - currencyUnit[cid[i][0]]*divide
        if (sub >= 0) {
         changes.push([cid[i][0], change])
        }

      } else {

        let divide = Math.floor(change / currencyUnit[cid[i][0]]);
        let unitChange = currencyUnit[cid[i][0]]*divide;
        let sub = cid[i][1] - unitChange;

        if (sub < 0) {
          changes.push([cid[i][0], cid[i][1]]);
          change -= cid[i][1];
        } else {
          changes.push([cid[i][0],unitChange])
          change -= unitChange;
        }
        change = Math.round(change * 100) / 100;
      }
    }
    let sum = 0;
    for (let i in changes) {
      sum += changes[i][1];
    }
    sum = Math.round(sum*100) /100
    if(sum == ch) {
      sufficient = true;
    }
    console.log("sum:" + sum);
  }
  

  console.log("Sufficient: "+sufficient);
  console.log(changes);
  console.log(ch)
  
  if (sufficient && cid[0][1]==ch) {
      console.log({
          status: "CLOSED",
          change:cid,
    })
      return {
          status: "CLOSED",
          change:cid,
    }
  } else if (sufficient) {
    console.log({
      status:"OPEN",
      change:changes,
    });
    return {
      status:"OPEN",
      change:changes,
    }   
  } else {
    console.log({
      status:"INSUFFICIENT_FUNDS",
      change:[]
    });
    return {
      status:"INSUFFICIENT_FUNDS",
      change:[]
    }
  }
  
  return result;
}
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]])