Cash Register project - decimal addition issues

Hello Campers, I’m trying to tackle the Cash Register project but I’m having trouble with every solution I try. After a convoluted solution that didn’t work, I planned a more efficient refactoring. I don’t have the code yet (still pseudocode), but in essence, what I want to do is first determine if the cash in the drawer is sufficient, equal or insufficient and then return the appropriate object. To do this, I tried using reduce to sum up all the available money, like so:

var totalMoney = cid.reduce( (acc, curr) => acc + curr[1])
console.log(totalMoney)

In essence, I’m using curr[1] to access the amount of currency as cid is a 2D array. However, outputing the sum in the console produces weird results, for example, 1.01 + 2.05 comes out as 3.0599999999999996. Even if I do it manually

console.log(1.01 + 2.05)

I get the same result. Ergo, I can’t go on to determine the appropriate if-block and solve the challenge. Is there anything I’m doing wrong? Thank you!

This is due to some floating point weirdness in JavaScript. I honestly can’t explain it that well, but here is a stack overflow post about it. https://stackoverflow.com/questions/588004/is-floating-point-math-broken

Here is another Stack Overflow post that addresses your problem. I like the second answer the best. https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary

1 Like

Thank you for the quick response. I understand this is due to the IEEE 754 representation (took some Comp Architecture classes) but still, I doubt the challenge wants to go in that kind of territory. Am I approaching this the wrong way?

The only other solution I tried was to just calculate the change and push it in an array, then determine if the funds where sufficient, then spaghetti and contort my code to return the correct object. Unfortunately, this worked for the “OPEN” and “INSUFFICIENT_FUNDS” cases, but “CLOSED” requires the original cid array which I mutated to calculate the money left. It doesn’t help that I can’t store it in a temporary variable as it is passed by reference!

const addDecimals = (num1, num2) => {
   return Number((num1 + num2).toFixed(Math.max(num1.toString().match(/\d+$/)[0].length, num2.toString().match(/\d+$/)[0].length)));
};

Why?

Everything is wrapped in Number(); // thus you ultimately get a number returned.
You pass in two numbers (num1, num2).
.match(/\d+$/) returns everything right of decimals.
Math.max returns the longest number of num1 & num2 after the decimal
.toFixed(variable) turns your number into a string,. with the effect of truncating after variable length.

Thus what this is saying is.,
return me a number, where num1 & num2 are turned into strings, shave off the digits after the decimal based on the longest string value between num1 & num2.

Keep in mind some really big numbers this will not work.

If you want something fancy you could always use this:

const addDecimals = (num1, num2) => Math.round((num1 + num2) * 1e12) / 1e12);