0

In the backend (Node.js) I save my prices in cents (*100) and always excluding VAT.
However, on the frontend we would like the user to be able to define their prices including VAT.

So what we do is as follows:
Price incl VAT: 10,00
Formula to incl VAT: (10*100)/1.21 which gives 826.4462809917355 Math.round it to: 826 The 826 is the price excl VAT which we save in the database.
But when we add the VAT (21%) to it, then it becomes this:

(826/100)*1.21

Which will become 999.4599999999999.
Math.round makes 999 of it.
So when our users filling in 10,00 as price incl VAT. It will end up being 9,99

Jesse
  • 645
  • 5
  • 8
  • Use `Math.ceil(999.4599999999999) === 1000` ? It rounds up – Jeremy Thille Feb 26 '20 at 10:54
  • Why are you saving `826` to the db and not `826.4462809917355 `? – Mortz Feb 26 '20 at 10:54
  • @JeremyThille Yes, but I think in some cases we do need to round down. Not sure if rounding up (ceil) works in every case – Jesse Feb 26 '20 at 10:55
  • Use `Math.floor(price + 0.5)` then. 9.1 gives 9, 9.4 gives 9, 9.5 gives 10, 9.6 gives 10, 9.9 gives 10 – Jeremy Thille Feb 26 '20 at 10:57
  • @Mortz not sure if storing floating numbers is the best solution to this. If it is, I'm happy to implement it though. But isn't that the same as adding more decimals? Thus all prices * 1000 or * 10000 instead of * 100? – Jesse Feb 26 '20 at 10:57
  • Please have a look at this answer regarding [float precision](https://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript) in JavaScript. – tin Feb 26 '20 at 10:57
  • @JeremyThille Thanks, I will try that out and check if I can find a number that doesn't work with that approach. – Jesse Feb 26 '20 at 10:58
  • I don't think it's a good idea to round any numbers when it comes to operations on the money. It's a very sensitive thing and after rounding up/down you may lose potentially a big amount of money because of that. You shouldn't even use primitive types to store floating-point numbers in that case. Some kind of sophisticated data type would be useful here (like `BigDecimal` in Java) to make sure you are not rounding anything up/down and not losing money. – Sebastian Kaczmarek Feb 26 '20 at 11:09

1 Answers1

0

The solution I went with is to increase the multiplier (100) to 100000.
Haven't had any issues with it since. Probably not a 100% solution, as I suppose this only reduces the change of issues.

Jesse
  • 645
  • 5
  • 8