I'm simply trying to define the scale at which you should be worried about using floats vs. doubles and ints vs. longs.

For all practical monetary values, you probably won't see these problems with doubles, but they could pop up with floats (albeit, rather large monetary values).

Take the previous code and run it with doubles (I would advise against trying to run this, it will take a while):

double poolF = 0;
long poolI = 0;
int individualContribution = 5;
for (long i = 0; i < 100000000000L; ++i) // even increased the number of contributors by 100x
{
poolF += individualContribution;
poolI += individualContribution;
}
System.out.printf("double pool amount = $%.2f\n", poolF);
System.out.println("actual (integer) pool amount = $" + poolI);

Even after 100 billion contributors, the double result has no error. Also, keep in mind that even with floats the code was able to get up to 1 billion contributors, a rather large amount in itself.

double pool amount = $500000000000.00

actual (integer) pool amount = $500000000000

Longs and integers will eventually experience "wrapping error". This happens when the mathematical operation takes the result physically out of the range of longs and integers (2^63-1 for longs, 2^31-1 for integers). In monetary terms, it's possible to overload an integer (~2 trillion), however like with doubles it's nearly impossible to conceive a practical case where longs would be overloaded (~9 sextillion).