Help with adding decimals in Cash Register

Tell us what’s happening:

I’m having an issue with this project involving adding decimal numbers. I’ve read about common errors that arise in JS when adding decimals such as 0.01 and 0.02 and getting a result like 0.02999… which is exactly the issue that I am having.

The second for loop in my code adds a type of currency to a total until it is equal to the amount of change that should be given. This works well up until it starts adding pennies. Around 96.72, when 0.01 is added, the result is something like 96.72999… which leads to the function always being one cent off.

My code below is using parseFloat and toFixed yet I’m still get 96.73 when I should be getting 96.74.

Any idea where I’m going wrong?

Your code so far


function checkCashRegister(price, cash, cid) {
// Cash given minus price of the item
let change = cash - price;

// Values of each den. of currency
let vals = [100, 20, 10, 5, 1, .25, .1, .05, .01];

// Holds the sum of the cash in the register
let totalCash = cid.flat().filter(a=>a/1).reduce((a,b)=>a+b);

// Holds the names of each currency type
let names = cid.flat().reverse().filter(a=>typeof a == "string");

// Holds the amount of each currency type
let amounts = cid.flat().reverse().filter(a=>a/1);

// Updated during the for loop, never resets.
let total = 0;

// Updated during the for loop, is reset
let sum = 0;

// Holds the amount of a certain currency: 20 in TWENTY would = 2
let amountOfCurrency = 0;

// Iterates through the cash in drawer to find the needed change
for (let i=0; i<vals.length; i++){
  // Counter that resets upon for loop reset
  sum = 0;
  amountOfCurrency = amounts[i]/vals[i];
  // If the current currency is <= change, and adding it to the total is as well...
  if (vals[i]<=change && total+vals[i]<=change) {
    for (let j = 0; j<amountOfCurrency; j++) {
      if (sum+vals[i]<=change && total+vals[i]<=change) {
        // Adds the current val to both sum and total:
        // if val[i] is 20, then 20 is added
        sum = parseFloat((sum+vals[i]).toFixed(2));
        total = parseFloat((total+vals[i]).toFixed(2));
        // Results are the same without parseFloat and toFixed:
        // sum+=vals[i];
        // total+=vals[i];
    console.log(`Added: ${sum} in ${names[i]}S`);
    // total is always 96.73, the change var is 96.74
    console.log(`Total: ${total}`);

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_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.2 Safari/605.1.15.

Challenge: Cash Register

Link to the challenge:

the issue is exactly as you say

1 Like

You aren’t wrong our making any mistakes
To sum up the video :3
You see the problem is that
The computer reads anything into binary
32 bit computers have a limit of the 23 significant numbers
and mess up where the point is
like a number which is times 2 to the something

in base 10 you can even do a lil test if u write 1/3 + 1/3 + 1/3 to the decimale the result for us humans becomes 1 right but the computer doesn’t understand the recurion
and it becomes
the 0.3333333333 etc
eventually becomes
untile they end up using the 23 digites and will cut

For this particular case, we can bypass the problem of floating point precision by changing our units from dollars (which require tracking decimals) to cents (which we can treat as whole numbers). If you multiply everything by 100 at the beginning of the logic and then divide everything by 100 at the end, you’ll get nice normal results.