Having rounding issues

Tell us what’s happening:
In the Cash Register challenge in JS Algorithms and Data Structures, I’m running into a problem with rounding. In the area of the code commented as //passing change to new array, I’m finding that the arithmetic operations that are happening are leaving me with imperfect results that are leaving me one penny short of my cash register working properly. I’m using Number(variable).toFixed(2) to round the results to two decimal places, but it doesn’t seem to be working. The operation that is being performed in this test case is 76.74 - 20. This leaves me with 56.739999999999995, which throws off all the rest of the calculations. As a proof of concept, if I write:
console.log(Number(76.74 - 20).toFixed(2))
I get 56.74, which is what I want. When the same operation is performed with variables instead of numbers, it doesn’t work. I’m kind of at a loss. Any ideas on what I’m doing wrong?

Your code so far


function checkCashRegister(price, cash, cid) {

  //setting up initial variables to work with
  let totalInRegister = 0;
  cid = cid.reverse();
  for (let i = 0; i < cid.length; i++) {
    totalInRegister += cid[i][1];
  }
  let output = {status:'', change: []}
  let difference = Number((cash-price).toFixed(2));

  //making sure there's enough in the register to perform the transaction
  if (difference > totalInRegister) {
    output.status = "INSUFFICIENT_FUNDS"
  }

  //adding a numeric version of each currency to cid
  for (let item of cid) {
    switch(item[0]) {
      case 'PENNY':
        item.unshift(0.01);
        break;
      case 'NICKEL':
        item.unshift(0.05);
        break;
      case 'DIME':
        item.unshift(0.1);
        break;
      case 'QUARTER':
        item.unshift(0.25);
        break;
      case 'ONE':
        item.unshift(1);;
        break;
      case 'FIVE':
        item.unshift(5);
        break;
      case 'TEN':
        item.unshift(10);
        break;
      case 'TWENTY':
        item.unshift(20);
        break;
      case 'ONE HUNDRED':
        item.unshift(100);
        break;
    }
  }
  
  //making a new array to pass the change to
  let cidCopy = []
  for (let i = 0; i < cid.length; i++) {
    cidCopy.push([cid[i][1], 0])
  }

  //passing change to new array
  for (let i = 0; i < cid.length; i++) {
    while (difference >= cid[i][0] && cid[i][0] <= cid[i][2]) {
      cidCopy[i][1] += cid[i][0];
      cid[i][2] -= cid[i][0];
      difference -= (Number(cid[i][0]).toFixed(2));
      //console.log so I can see what's happening;
      console.log(difference)
    }
  }
  
  //making an array to populate with final change and pass to output
  let toPass = [];
  for (let i = 0; i < cidCopy.length; i++) {
    if (cidCopy[i][1] > 0) {
      toPass.push(cidCopy[i]);
    }
  }
  
  //passing change to output
  output.change = toPass;

  //getting the total in toPass for comparison against register
  let toPassTotal = 0
  for (let i = 0; i < toPass.length; i++) {
    toPassTotal += toPass[i][1];
  }

  //comparing the total change given to the remaining total in the register
  if (toPassTotal < totalInRegister) {
    output.status = 'OPEN'
  } else if (toPassTotal == totalInRegister) {
    output.status = 'CLOSED'
  }
  
  return output;
}

// Example cash-in-drawer array:
// [["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]]);

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0.

Link to the challenge:

Use integers then divide to dollar amounts at the end, otherwise you’ll get floating point errors.

2 Likes

convert all your decimals to whole numbers before doing math with them, and convert back to decimals before returning the values

1 Like