# Cash Register and the revelation that computers can't do dimes (at least without any workaround)

Tell us what’s happening:
After reading about floats and how they are portrayed in binary, and learning about the `Number` object, and painstakingly debugging the rounding problem, I finally slapped together this monstrosity of a code.

There is a few things that I’m not happy with in it though, mostly the performance aspect, so I hope someone can give me advice on them:

1. I have to use 2 `for` loops in the `giveNum` function just to make a new array where the value of each bill is added so it can be worked on easier, and that makes 81 boolean checks just for 9 actions. I wonder if I can make it more efficient, maybe array-wide methods or binary checking can do so, but I can’t figure out how to make that work.

2. The subfunction `calcAmountOfBill` originally was:

``````let calcAmountOfBill = (num,i) => {
let max = cid[i]/cid[i];
let div = ((num-(num%cid[i]))/cid[i]);
return div>=max?max:div;
}
``````

instead of painstakingly running a loop until the double brake hits (50 pennies). But the loops holds against the floats, and my cheeky math doesn’t.

I can’t find a way to avoid the rounding problem to make it works correctly with floats. The inaccuracy either stacks each time the function loops for each bill until it’s apparent, or show up at the last computation (for the 50 pennies check, it always either returns `remain` as a non-0 value, or return `div=49` instead of the correct 50) no matter what type of rounding technique I use. If anyone have any insight or a solution to help it works, please teach me.

1. I’m not really happy about how this piece of code has to repeat itself instead of being put inside the subfunction `calcAmountOfBill` (was my initial plan):
``````if (j!=0) {
changeArr.push([arr[i],arr[i]*j]);
remain = floatFixer(remain-arr[i]*j);
arr[i] -= arr[i]*j;
}
``````

When I tested it, I figured out `changeArr` and `remain` was only updated locally and not carried over into the main function, so I have to bring them out. I wonder if there is a way for you to return things like the result of an `Array.push`, or an upper-layer array element’s edit from inside a function into the upper-layer.

That’s everything, thank you for reading. I’m sure some people will find these questions ridiculous, but if you can give me answers and your insight on them, you are a great and smart person and I love you for that ``````let unit = [
["PENNY", 0.01],
["NICKEL", 0.05],
["DIME", 0.1],
["QUARTER", 0.25],
["ONE", 1],
["FIVE", 5],
["TEN", 10],
["TWENTY", 20],
["ONE HUNDRED", 100]
]

function checkCashRegister(price, cash, cid) {
let change = cash-price;
let total = null;
for (let i of cid) {
total += i;
}
total = floatFixer(total);
let calc = changeCalc(change,giveNum(cid));
let changeStack = calc;
let unpaid = calc;
let result = new Object;
if (unpaid != 0) {
result.status = "INSUFFICIENT_FUNDS";
result.change = [];
}  else if (total == change&&unpaid == 0) {
result.status = "CLOSED";
result.change = cid;
} else {
result.status = "OPEN";
result.change = changeStack;
}
return result;
}

function floatFixer (num) {
num = Number((num*(1+Number.EPSILON)).toFixed(2));
return num;
}

function giveNum (arr) {
let dup = JSON.parse(JSON.stringify(arr));
for (let i = dup.length-1;i >= 0;i--) {
for (let j of unit) {
if (dup[i]==j) {
dup[i].push(j);
}
}
}
return dup;
}

function changeCalc(change,arr) {
let remain = change;
let changeArr = new Array;
let calcAmountOfBill = (num,i) => {
let j = 0;
while (arr[i]*(j+1)<=num&&arr[i]>arr[i]*j) {j++};
return j;
}
if (remain>=arr[arr.length-1]) {
let j = calcAmountOfBill(remain,arr.length-1);
if (j!=0) {
changeArr.push([arr[arr.length-1],arr[arr.length-1]*j]);
remain = floatFixer(remain-arr[arr.length-1]*j);
arr[arr.length-1] -= arr[arr.length-1]*j;
}
};
for (let i = arr.length-2;i >= 0;i--) {
if (arr[i]<=remain) {
let j = calcAmountOfBill(remain,i);
if (j!=0) {
changeArr.push([arr[i],arr[i]*j]);
remain = floatFixer(remain-arr[i]*j);
arr[i] -= arr[i]*j;
}
}
}
return [changeArr,remain];
}

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

User Agent is: `Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0`

Challenge: JavaScript Algorithms and Data Structures Projects - Cash Register

1. You might opt to assume that both arrays have corresponding denominations at the same indices. Some other option could be using object for units, instead of array, it’d map denomination name to the value without needs for additional checks or nested `for` loop.