> Sometimes I see other people fuck up a project over and over, and I say “I could do that better”, and then I get a chance to try, and I discover it was a lot harder than I thought, I realize that those people who tried before are not as stupid as as I believed. That did not happen this time. Moonpig is a really good billing system. It is not that hard to get right. Those other guys really were as stupid as I thought they were.
Your balance is $0.30000000004
41–50 of 69 posts
Re: Your balance is $0.30000000004
#42Re: Your balance is $0.30000000004
#43Earlier quoted context omitted.
This approach doesn't work when dealing with fractional cents, like charging $0.0001 per hour for something. I would rather recommend using an arbitrary precision decimal library like Decimal.js, and using strings to represent money in JSON. And of course using an appropriate database type for storing the data.
Just make the smallest possible fractional cent the unit then
What you gain by consistently using an arbitrary precision decimal library to process all monetary values, is the freedom to process smaller fractions later if necessary. Also you'll never overflow with really big values.
In other words, when you represent monetary values with arbitrary precision Decimal objects everywhere, you can easily expand your application as much as you want on either side of the decimal dot. Changing existing integer-based code do to that is very error-prone, you quickly lose sight of what exactly an integer value or parameter means in different places.
Re: Your balance is $0.30000000004
#44Work with cents everywhere and format the output in the UI. Done.
Re: Your balance is $0.30000000004
#45Earlier quoted context omitted.
browser console: (1.005).toFixed(2) (1.005).toFixed(20) reveals the problem. Math.round(1.005 * 100) // wrong In the end these conversion errors are not solvable in any language, so you have to "cut off" somewhere. There are different approaches to this. Wasn't there a case where programmers stole the "wrong" cent and wasn't The Office a persiflage on that?
> In the end these conversion errors are not solvable in any language Not true at all. Ruby has BigDecimal: https://ruby-doc.org/stdlib-2.5.1/libdoc/bigdecimal/rdoc/Big... .NET also has a Decimal type. I've worked on salary calculation applications and e-commerce platforms, and found that language choice makes a big difference.
Re: Your balance is $0.30000000004
#46I'm currently rewriting our store implementation, and it's complicated. One example is that some currencies have 100 subunits (eg USD), some have 10 subunits (EG TWD/MOP) and some have no subunits (eg JPY). This is made slightly more difficult in that Stripe/Paypal will treat subunits differently, for example Paypal might treat JPY as having 100 subunits and Stripe will treat it with 0 subunits. You want to be really…
Re: Your balance is $0.30000000004
#47Work with cents everywhere and format the output in the UI. Done.
In JavaScript:
> p=2500; r=0.347;
Math.round(p*r)
You need to integerize the percentage, too. For my current financial applications, all the percentages I need are integer multiple of 0.01%, so I use that as my "percent cent". 34.7% is then represented as 3470.That leads to a function something like this (assuming you need the 0.5 round up rule...changing it to 0.5 rounds to even is left as an exercise):
function percent(amt2, rate4)
{
return Math.floor((amt2 * rate4 + 5000)/10000)
}
(The 2 and 4 suffixes are a naming convention I use. They are reminders that amt2 is the underlying amount x 100, and that rate4 is the underlying rate x 10000).Re: Your balance is $0.30000000004
#48Martin Fowler's money pattern [0] solves this problem. Just make sure whenever you're dealing with currencies to use a value object for money, rather than float. Lots of languages have libraries for this pattern. [1] [0] - https://www.martinfowler.com/eaaCatalog/money.html [1] - https://github.com/topics/fowler-money-pattern
One thing I've always wondered is who the heck is Martin Fowler and why does he have such a following?
You don't know the history of your craft; study more, look into where agile came from, the extreme programming movement, and who was involved and how refactoring became a thing. Names like Ward Cunningham, Kent Beck, Martin Fowler, Ron Jeffries, Rob Martin, and Dave Thomas should be familiar to anyone who knows their craft.
Re: Your balance is $0.30000000004
#49I'm currently rewriting our store implementation, and it's complicated. One example is that some currencies have 100 subunits (eg USD), some have 10 subunits (EG TWD/MOP) and some have no subunits (eg JPY). This is made slightly more difficult in that Stripe/Paypal will treat subunits differently, for example Paypal might treat JPY as having 100 subunits and Stripe will treat it with 0 subunits. You want to be really…
Re: Your balance is $0.30000000004
#50Work with cents everywhere and format the output in the UI. Done.
Really the only foolproof method is to use rationals - numerators and denominators.