In real terms, how much money is a project losing if we always round down?
At 100 patrons, it’s 10% max (technically 9%, but I like round numbers). By 1000 patrons, it’s 1%. 10k → 0.1%, etc.
10% is a lot, but nobody is going to care about that, because a project with 100 patrons isn’t making anything anyway (the first payout wouldn’t happen for 2.5 years). And, of course, those are the upper bounds; it should actually average to half that.
On the other hand, what do you do in the following scenario?
- I support two projects, A and B
- I am the only patron of both projects
- Project A has 20 other patrons
- Total income = 2.1¢ * 21 patrons = 44.1¢
- Project B has 18 other patrons
- Total income = 1.9¢ * 19 patrons = 36.1¢
To make mental math easier, let’s assume we do payout every month. We’re not losing anything doing this since I could easily make an equivalent example where the patron numbers are high enough to put things above the threshold. So, the first payout happens.
- Other patrons of project A are paying 2.1¢
- They (20) are each charged 2¢ with 0.1¢ carried over → 40¢ total
- Other patrons of project B are paying 1.9¢
- They (18) are each charged 1¢ with 0.9¢ carried over → 18¢ total
- I am am charged 1.9¢ + 2.1¢ = 4¢, with no carry-over.
How do we divvy up the funds?
-
Sum all the charges and then divide them proportionately.
- We charged patrons a total of 61¢.
- Un-rounded project total income is 44.1 + 36.1 = 80.2¢
- Project A is 44.1/80.2 = 0.5498… and B is 36.1/80.2 = 0.4501…
- Multiplying those fractions by 61¢ yields 33.54…¢ and 27.45…¢.
Problems with this method:
- We can’t actually do the full payout to projects without rounding.
- In this example, we’d have to give project A 34¢ and project B 27¢.
- Projects’ income consistency is affected by other projects. If project B didn’t exist, A would get 42¢ each month; instead,
- In fairness, this is a much smaller concern as we get to amounts of money anybody cares about.
- Also in fairness, this is the case regardless of payment method, because pledging to other projects affects when you hit the minimum charge.
-
Maintain individual balances for each patron/project.
- Project A receives 42¢ (40 from others; 2 from me)
- Project B receives 19¢ (18 from other, 1 from me)
- Note: in this scenario, I get charged 3¢, not 4¢, with a pending balance of 0.1¢ to project A and 0.9¢ to project B.
Problems with this method:
- I have a pending donation (of 1¢) that could be charged but isn’t. This could be confusing to show & make our dashboard more complicated.
Also, with any scenario where we allow pledges to happen in fractions of a cent, we can have “infinitely pending donations”, when a patron decides to stop pledging and their outstanding balance is in fractions of a cent. This isn’t a problem in terms of reduced income for projects, since it would be rounded down otherwise, but it does create a scenario where projects have might believe they have pending donations, that they will never actually receive.
Fractions of a cent are fine. We use them in the real world for things like gas prices, as wolftune mentioned. But that works precisely because purchases are rounded to the nearest cent at the time they’re made, not on an ongoing basis.
I agree that the code would be simpler/better if we never rounded, but I’m not convinced this is worth the trade-off in real-world complexity. Do you know of any examples of repeated, fractional-cent, non-refundable transactions which are charged in aggregate? That would go a long way towards convincing me it’s a good choice.