Crowdmatching dollar amounts inaccurate

bug

#1

On the dashboard page of the live website, it says that my pending donation is $0.50. However, when I add up all the crowdmatchs (crowdmatches?) to date, it only adds up to $0.42.

I KNOW, that what is happening is that my monthly donations are actually $0.081 to $0.087 instead of simply $0.08. I think this should be clearly shown on the dashboard page. Someone who just signs up and hasn’t read up on this project as much as I have might not understand.


#2

I think the correct way to do this is not charge the fractions of pennies. Ie, your pending donation actually should be $0.42.

@msiep and @mray should make the official decision on that, though.


#3

Numbers should add up. No matter how and why they got rounded, but I guess solving this glitch falls under “nice to have” – in terms of priority. I would suggest opening an issue in gitlab anyway.


#4

Done: https://git.snowdrift.coop/sd/snowdrift/issues/108


#5

I agree numbers should add up.

The rounding you see was whatever I happened to do in the five seconds I was putting together the HTML for that table.

We could go a few ways.

  1. Actually round donations
  2. Fudge the sum
  3. Show the whole, fractional number

I’m in favor of showing the whole, fractional number. Fudging is bad, and rounding donations would cost projects an average of half a penny per patron.

Would showing fractions of a penny be confusing? @msiep?


#6

I’m in favor of actually rounding donations. Fudging is bad and a half-cent per patron is a tiny margin of error for projects which amounts that actually matter.[1]

Showing fractions adds non-trivial complication. For example, @CANAWEN would have needed a calculator to make this thread.


  1. We could even round up half of the time, for effectively no cost. ↩︎


#7
redundant balanced rounding comment, collapsing for brevity

If rounding went both ways, wouldn’t it even out? So:

  • 3 patrons→ 0¢ each
  • 4 patrons→ 0¢ each
  • 5 patrons→ 1¢ each
  • 6 patrons→ 1¢ each

etc.

EDIT: @smichel17 said this in his footnote just the same time I posted


#8

I don’t think so. Most people would understand that we’re dealing with fractions of a penny. It would only be an extra decimal point anyways. I’m against rounding. Rounding adds complexity to a system that people already take a while to wrap their head around. Showing the extra decimal point is an easy and transparent way to communicate what is happening.


#9

You can’t charge a fraction of a cent. There are 3 ways to deal with this (round always means down here, for simplicity):

  1. Never round donations. Round charges and carry over the remaining fraction.
    • Added complexity: Lots of fractional carry-overs.
  2. Round donations at charge time. Same as (1), but with no carry-over.
    • Added complexity: Deciding who loses the fractions we throw out.
  3. Round at crowdmatch time. Monthly donations are always whole cents.
    • Added complexity: Understanding that donations are rounded.

None of these solutions are actually free of rounding entirely, so solutions 1 and 2 don’t actually shield patrons (or projects) from that complexity. Solution 3, on the other hand, isolates it to crowdmatch time, where it doesn’t seep out into our database or other designs, etc.

edit: I think the rounding is easier to understand at crowdmatch time. “You pledge to donate a tenth of a cent per patron, rounded to the nearest cent” seems a lot simpler than having to think about fractions of a cent all over the place (especially if we ever switch from tenths to a messier fraction).


#10

I’d say it depends on whether we are about to inform about actual sums of money – or – get along the concept of the mechanism. I this case I think it makes no sense to display amounts of money that are impossible to pay.

It also adds visual clutter and makes recognizing the actual value slightly harder (as penny amounts usually are never longer than two digits)


#11

FWIW, three-decimal dollar values are so unusual, it will throw people off if we show it that way. If we ever show the extra tenths, it should be shown distinctly, such as a fraction, as in the real-world case of gasoline prices:

Otherwise, single-decimal cents with the ¢ symbol are more functional, but will themselves look weird for numbers beyond $1 (i.e. 100¢)


#12

No, but the fractions can add up to real money® when you have multiple patrons supporting multiple projects. Heck, they add up to real money when there are multiple crowdmatch events leading up to a payout event, as in the current situation. If the threshold was only $0.50, CANAWEN could pay $0.50 in real money this month, even though that number is due to ~6 months of fractional crowdmatch pennies.

I really don’t like rounding, even if we used financial rounding. It’s weird to “match” nonexistent people (in the case of rounding up). I don’t like the idea of complicating the model to simplify the presentation, either.

I also do like the idea of keeping track of the fractions, for the reasons I state above.

I am open to other ideas for simplifying the presentation. Only show the number of patrons matched, perhaps? Use a consistent and uniform display for match amounts that are distinct from charges? (Since charges always will be in real money.)

Any indirection we add between the actual match amount and the way it’s presented will need some modification if we add a knob to adjust the “0.1¢ per patron” multiplier, but we can worry about that at another time.


#13

Sorry for not responding to this for so long. It started just before I went on vacation.

I don’t think there’s any “understanding” problem with rounding (using the standard of rounding .5 and higher up and lower than .5 down) as long as the rounding is done before any summing etc. So we’d just always show rounded to the nearest cent, and any totals would be totals of the rounded amounts, NOT rounded totals of the precise amounts. This way the problem @CANAWEN pointed out would not occur.

To summarize, I don’t think we should ever show fractions of cents, and we should always round before summing.


#14

I updated the issue to reflect this:

If we actually do the rounding in the backend when numbers become a dollar (or cent) related type, then there will be no concern for a modification between the front and back end, and everything will work with adjustable crowdmatch base amounts too.

further discussion?

(if there’s any further concerns about this direction, I won’t weigh in. @msiep and @chreekat you two can hash out backend vs frontend balance. I just was aiming to keep the decision here tied to the GitLab issue.


#15

Ironically, this highlights a subtle problem of rounding as it applies to discrete numbers. Since we’re dealing with tenths, fully 1/10 of them are exactly halfway between the whole number (0.5, 1.5, 2.5, etc). This means that 10% of the time, we’d be inflating the donation value. (This isn’t a problem with real numbers, since e.g. 1.5000000000000000000000 is pretty rare.)

To deal with this, there’s an alternate rounding scheme that “rounds to even”: 1.5 and 2.5 both round to 2, 3.5 and 4.5 round to 4, etc. This gets rid of the systematic bias, but is clearly more complicated. In fact, rounding is complicated enough that the Wikipedia article lists over a dozen methods!

My experience tells me we should not introduce rounding at all in the backend calculations. We have no need for it, and it just invites trouble. It makes audits harder and mistakes easier.

Whether or not we round any numbers on the frontend can still be discussed…


#16

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¢[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?

  1. 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.
  2. 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.


  1. rounding up to 2¢ would be really nice here, but overcharging people when we are explicitly not rounding seems like a legal recipe for disaster, though maybe a lawyer would feel differently and everything would be OK. ↩︎


#17

@chreekat this is an intriguing point that hadn’t occurred to me, but do you feel there’s a realistic concern that patrons would get upset about this? Even if we always rounded up, that would only affect how much each patron donated to each project each month by at most one cent, compared to the other extreme of always rounding down. It still seems to me that we should follow the standard of rounding 0.5 or higher up and below 0.5 down on the back end, so we never have any fractions of cents represented anywhere in the system.


Planning meeting agendas in advance
#18

Another option is just to have $0.01 be the smallest unit in the calculation. that way, we never have to round. I think its also more transparent, and easier for people to conceive / understand. Everyone can visualize a penny.


#19

Reading through @smichel17’s post, I realized something that makes me much inclined to agree we should just use cents. We don’t want eventual consistency between charges and donations, we want instantaneous consistency. I think Stephen overlooked elements of the mechanism that do ensure consistency, but that consistency is only eventual, because payments and donations are processed separately. We’d be hanging on to people’s money (pennies, to be sure) until the next round of donations.

Anyway, the important point is that I’ve come around. We have to round something, somewhere, in order to have instantaneous consistency.

Unfortunately, that doesn’t lessen the risk of screwup that rounding entails. Let’s think about this some.


#20

I don’t like this trade-off, but it’s always possible to simply say “1¢ for every 10 patrons” even though it’s not ideal in that each new patron isn’t strictly matched (we’d have recurring 10-patron thresholds), and each pledge doesn’t immediately increase the instantaneous crowdmatch amount from everyone else.

Another option to consider: round down at the charge point, just carry over the fractions of a cent. This leaves some money on the table, so to speak, but it’s just pennies. In this case, there’s no rounding even at crowdmatch points, everything just adds up until a patron has a balance large enough to charge, but we carry-over the fraction of a cent to the next future charge.

The weirdest challenge would be managing how that would work when a charge includes donations to multiple projects.