0

This while loop essentially finds what's the best unit of the currency to give back to the customer considering what is in the drawer and adds it to the change array.

    while (difference > 0) {
        var unit = Object.keys(currency).reverse().reduce((output,prop)=>{
            if (difference >= currency[prop] && cid[prop] >= currency[prop]) {
                output.push(prop, currency[prop]);
            } else {}
            return output;
        }, []);
        cid[unit[0]] -= unit[1];
        difference -= unit[1];
        change.push(unit);
    }
  • cid is cash in drawer
  • List item

difference is prince minus cash

I could obviously cheat but a better solution would be preferable.

xgreed
  • 25
  • 6
  • can you give a [minimal reproducable example](https://stackoverflow.com/help/minimal-reproducible-example) ? – Jannes Carpentier Aug 05 '20 at 19:24
  • Doing "money math" in JavaScript is intrinsically difficult because decimal fractions cannot always be represented exactly. – Pointy Aug 05 '20 at 19:43
  • @JannesCarpentier 0.01 >= 1-0.99 ... expected evaluation true, actual evaluation false (in Chrome). JavaScript just does not have the best math. – user3067860 Aug 05 '20 at 20:31
  • Multiply everything by 100 and work with cents instead of euros/dollars, then you avoid floating points – Jannes Carpentier Aug 05 '20 at 20:38
  • Does this answer your question? [Why not use Double or Float to represent currency?](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) – chtz Aug 05 '20 at 21:52
  • @chtz thank you it was helpful. I'll just avoid floating point all together like Jannes pointed out. – xgreed Aug 05 '20 at 23:21

1 Answers1

0

As Pointy mentioned in comments, JavaScript is not really designed for floating point math (actually it is decimal floating point math that it's not good at, if everything is base 2 you are fine).

For example, in Chrome,

0.01 >= 1-0.99

evaluates to false.

This previous answer has a more thorough explanation, including the official answers about what to do.

But for me, it's not cheating to convert all your numbers to an integer number of cents before doing calculations. A lot of software development is finding ways to translate normal human things into things that can be done efficiently by computer and representing decimal money as an integer number of cents works logically.

user3067860
  • 456
  • 4
  • 11
  • JavaScript is designed for floating-point math. Floating-point math is not designed for simplistic currency calculations. – Eric Postpischil Aug 06 '20 at 20:03
  • @EricPostpischil Fixed to specify that it's decimal floating point math that JS is terrible at. (Other languages at least make an effort to make 5th grade arithmetic work as expected out of the box, without the user having to jump through hoops.) – user3067860 Aug 07 '20 at 14:54