Why did I have to use two different solutions to specify two decimal places in the Cash Register project?

I solved the cash register project found here. I needed to use the x100/100 way to specify two decimal places for the cidAmount on line 30. I needed to use the .toFixed(2) method on lines 37 and 40 to specify two decimal places for the changeAmount and cidCopy[i][1], respectively. My code would give me weird results if I just used one of the solutions for everything. Thanks for any help.

"use strict";

function checkCashRegister(price, cash, cid) {
  var changeToCustomer = {status: "OPEN",
   change: []};
  // Here is your change, ma'am.

  let cidCopy = [];

  for (let x = 0; x < cid.length; x++) {
    cidCopy[x] = cid[x].slice();
  }

  let changeAmount = cash - price;

  let cidAmount = 0;

  let denominationCount = 0;

  let denominationAmount = [0.01, 0.05, 0.10, 0.25, 1.00, 5.00, 10.00, 20.00, 100.00];
  
  let denominationName = ["PENNY", "NICKEL", "DIME", "QUARTER", "ONE", "FIVE", "TEN", "TWENTY", "ONE HUNDRED"];

  let changeGiven = 0;

  for(let i = 0; i < cidCopy.length; i++) {
    cidAmount += cidCopy[i][1];
  } 

  cidAmount = (cidAmount * 100) / 100;

  for (let i = cidCopy.length - 1; i >= 0; i--) {
    while (changeAmount >= denominationAmount[i] && cidCopy[i][1] > 0) {
      denominationCount++;

      //For keeping track of entire change amount.
      changeAmount = (changeAmount - denominationAmount[i]).toFixed(2);
      
      //For keeping track of current denomination amount in drawer.
      cidCopy[i][1] = (cidCopy[i][1] - denominationAmount[i]).toFixed(2);
    }

    if (denominationCount > 0) {
      changeToCustomer.change.push([denominationName[i], denominationAmount[i] * denominationCount]);
    }

    denominationCount = 0;
  }

  for (let j = 0; j < changeToCustomer.change.length; j++) {
    changeGiven += changeToCustomer.change[j][1];
  }

  if (changeAmount > cidAmount || changeGiven < changeAmount) {
    changeToCustomer.status = "INSUFFICIENT_FUNDS";
    changeToCustomer.change = []; 
  }
  else if (changeGiven === cidAmount) {
    changeToCustomer.status = "CLOSED";
    changeToCustomer.change = cid;
  }
  else {
    changeToCustomer.status = "OPEN";
  }

  return changeToCustomer;
}

// 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(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]);

it depends on the number itself

you can use a simple method if the first thing you do is to convert everything to cents (multiply by 100, and rounding to make sure you have whole numbers), and then the last thing divide by 100 to get again the value in dollars

otherwise at each step with decimals the calculations may have a lot of trailing numbers. The reason? Maths in base 2 with a finite number of places:

2 Likes