| Author |
Can you do money calculations without BigDecimal?
|
Pat Farrell
Rancher
Joined: Aug 11, 2007
Posts: 4422
|
|
Never use float or double for money. Store the integer number of pennies. This works for US, Canadian, Austrailian, etc. dollars, Euros and other kinds of money.
Then use Formats to add or remove the decimal points into the right places.
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5901
|
|
Pat Farrell wrote:Never use float or double for money.
Generally not for real money in real production applications. For educational purposes double is generally fine sometimes acceptable if accompanied by an explanation and demonstration of its shortcomings, along with what alternatives are available. [EDIT: Okay, I've qualified my statement. Still not buying into "never" though.)]
Store the integer number of pennies.
Or use BigDecimal.
Then use Formats to add or remove the decimal points into the right places.
I don't think that will work. I don't think you can use the formatting tools in the core API to add decimal points to integers. You'd have to roll your own, I believe.
|
 |
Pat Farrell
Rancher
Joined: Aug 11, 2007
Posts: 4422
|
|
Jeff Verdegan wrote:
Pat Farrell wrote:Never use float or double for money.
Generally not for real money in real production applications. For educational purposes double is generally fine.
I strongly disagree that it is OK for educational purposes. It teaches bad design. It teaches that it is OK to use something that simply will not add up. Rounding problems happen quickly and for small amounts. The last textbook that I used for teaching a college level class had examples using double. I spent a full lecture teaching why this is a terrible example and a terrible thing to teach in a Java 101 class.
|
 |
Bear Bibeault
Author and ninkuma
Marshal
Joined: Jan 10, 2002
Posts: 56229
|
|
|
I'll second Pat on that. For no purposes at all should double or float ever be used for money. Ever.
|
[Smart Questions] [JSP FAQ] [Books by Bear] [Bear's FrontMan] [About Bear]
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5901
|
|
Pat Farrell wrote:
Jeff Verdegan wrote:
Pat Farrell wrote:Never use float or double for money.
Generally not for real money in real production applications. For educational purposes double is generally fine.
I strongly disagree that it is OK for educational purposes. It teaches bad design. It teaches that it is OK to use something that simply will not add up. Rounding problems happen quickly and for small amounts.
I don't generally buy into "never."
If coupled with the admonition that it's not appropriate in most real business scenarios, possibly with a demonstration of why, I think it's perfectly appropriate. It teaches one to evaluate the pros and cons and when the limitations are acceptable. Especially if it's followed up with, "Now do this exercise using BigD."
For example:
This tells me that for 10k transactions in the $10k range, the cumulative error is a little over 1/1,000th of a penny. This is acceptable for a vending machine exercise, or an app I write to track my kids' part time job earnings, or cash flow "what if" scenarios for a small mom-and-pop store. I'm certainly not going to muck about with BigD for any of those cases (unless the instructor requires it for the vending machine exercise).
It also tells me that a million transactions in the $1M range leads to an error of around $8, which, while still very small proportionally, is not acceptable from an accounting standpoint.
So we learn about trade-offs.
|
 |
Bear Bibeault
Author and ninkuma
Marshal
Joined: Jan 10, 2002
Posts: 56229
|
|
Still disagree. At an early stage, the student will not learn about trade-offs, they're too busy trying to learn the basics -- they'll simply learn the bad habits.
Teaching theory 101: teach one concept at a time.
Sort of like "We'll use scriptlets in a JSP because it's easy, but you shouldn't do that in real code". Result? The "shouldn't do that" might just as well have been spoken into the drainpipe and everyone still uses scriptlets in JSPs 10 years after their obsolescence.
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5901
|
|
Bear Bibeault wrote:Still disagree. At an early stage, the student will not learn about trade-offs, they're too busy trying to learn the basics -- they'll simply learn the bad habits.
Teaching theory 101: teach one concept at a time.
And I continue to disagree with your disagreeing. One can do what I suggested and still teach one concept at a time. Double will probably be introduced before BigD. This can be done with a non-money example. Then when it's time to teach the concept of the limitations of floating point numbers, we can use money to show where it falls flat and introduce BD.
|
 |
Pat Farrell
Rancher
Joined: Aug 11, 2007
Posts: 4422
|
|
Jeff Verdegan wrote: Double will probably be introduced before BigD. This can be done with a non-money example. Then when it's time to teach the concept of the limitations of floating point numbers, we can use money to show where it falls flat and introduce BD.
I've never seen a Java 101 text that teaches double in any meaningful way. Its useful for engineering calculations. Or physics or astronomy, etc. Most of my students have not seen Calculus when they take Java 101. So they can't handle physics or engineering as examples. I've also never seen BigDecimal covered in a Java 101 course. In the last course I taught, the department-defined syllabus barely got to inheritance.
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5901
|
|
Pat Farrell wrote:
Jeff Verdegan wrote: Double will probably be introduced before BigD. This can be done with a non-money example. Then when it's time to teach the concept of the limitations of floating point numbers, we can use money to show where it falls flat and introduce BD.
I've never seen a Java 101 text that teaches double in any meaningful way. Its useful for engineering calculations. Or physics or astronomy, etc.
Or money calculations when the scale of the numbers your dealing with is such that error is small enough to not make it worth the hassle of using BD.
Most of my students have not seen Calculus when they take Java 101. So they can't handle physics or engineering as examples.
They've probably ad least had, or are taking, algebra right? There's plenty of simpler stuff that can be taught using double. The students certainly have been introduced to the concept of decimal points, yes?
I've also never seen BigDecimal covered in a Java 101 course. In the last course I taught, the department-defined syllabus barely got to inheritance.
Who said anything about teaching it in Java 101? What I did say is that when the time does come to teach it, the students should already have at least some familiarity with double, and so this is a good time to introduce (or revisit) the inherent inaccuracies and their effects.
|
 |
Pat Farrell
Rancher
Joined: Aug 11, 2007
Posts: 4422
|
|
Jeff Verdegan wrote:[Who said anything about teaching it in Java 101?
This is the "beginning java" section. I was talking about my experience teaching university courses of Java 101.
You, Jeff, are just being disagreeable and not helping the OP.
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5901
|
|
Pat Farrell wrote:
Jeff Verdegan wrote:[Who said anything about teaching it in Java 101?
This is the "beginning java" section.
Fair enough. There's so much overlap between BJ an JiG I don't generally pay attention to which one I'm in. On the other hand, since we are discussing the limitations of FP numbers, I think it's fair to introduce BigDecimal and to give some idea of when those limitations do and don't matter.
I was talking about my experience teaching university courses of Java 101.
Yeah, I got that. The way you introduced it seemed to imply it had some bearing on the points I was making.
You, Jeff, are just being disagreeable and not helping the OP.
Just because I'm disagreeing does not mean I'm being disagreeable. And I think that understanding why people are saying not to use double, and when it's okay to do so, is in fact helpful.
|
 |
Martin Vajsar
Bartender
Joined: Aug 22, 2010
Posts: 2335
|
|
|
This discussion originated in the Money and digits problem thread in the Beginning Java forum. I've moved posts not related to the original question here.
|
 |
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2782
|
|
Jeff Verdegan wrote:
Pat Farrell wrote:Then use Formats to add or remove the decimal points into the right places.
I don't think that will work. I don't think you can use the formatting tools in the core API to add decimal points to integers. You'd have to roll your own, I believe.
I took Pat's comment to mean: use a Format along with some simple math - not necessarily a Format by itself. E.g.
Or, using String.format():
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5901
|
|
Mike Simmons wrote:
Jeff Verdegan wrote:
Pat Farrell wrote:Then use Formats to add or remove the decimal points into the right places.
I don't think that will work. I don't think you can use the formatting tools in the core API to add decimal points to integers. You'd have to roll your own, I believe.
I took Pat's comment to mean: use a Format along with some simple math - not necessarily a Format by itself. E.g.
Yeah, I had a total brain f**t about that. Just wasn't thinking.
|
 |
Pat Farrell
Rancher
Joined: Aug 11, 2007
Posts: 4422
|
|
Jeff Verdegan wrote:Yeah, I had a total brain f**t about that. Just wasn't thinking.
Happens to us all occasionally.
I generally write the code something like:
String outStr = String.format("%d.%02d", amount/100, amount %100);
To answer the direct question, on a 32 bit machine, you can have 2 billion pennies, or 20 million dollars, and all of your arithmetic will work perfectly. So you can just use the int number of pennies for personal finance, and small businesses. But most large businesses have budgets that are over 20 million dollars, so for them, you have to do more complex stuff.
In all but the most trivial cases, I recommend writing a Money class and using it, so you can change the implementation details if/when you have to.
|
 |
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2782
|
|
Pat Farrell wrote:To answer the direct question, on a 32 bit machine, you can have 2 billion pennies, or 20 million dollars, and all of your arithmetic will work perfectly. So you can just use the int number of pennies for personal finance, and small businesses. But most large businesses have budgets that are over 20 million dollars, so for them, you have to do more complex stuff
I typically would just use a long to avoid this issue. If there's a business where that's not good enough, I want to work there.
Pat Farrell wrote:In all but the most trivial cases, I recommend writing a Money class and using it, so you can change the implementation details if/when you have to.
Agreed.
|
 |
Pat Farrell
Rancher
Joined: Aug 11, 2007
Posts: 4422
|
|
Mike Simmons wrote:I typically would just use a long to avoid this issue. If there's a business where that's not good enough, I want to work there. 
Of course, on both parts. long is much bigger than int. A long can hold 9,223,372,036,854,775,807 pennies, which is 92,233,720,368,547,758.07 dollars/euros/etc. which is 92 quadrillion, 233 trillion, 720 billion, 368 million dollars and change
Long ago, I did an accounting system for the US GAO, and we had to deal with dollar amounts in the size of the US budget. At the time, it was hundreds of billions, now its a few trillions.
I also worked at Fannie Mae, where they would often talk about bundles of mortgages that were billions of dollars.
|
 |
 |
|
|
subject: Can you do money calculations without BigDecimal?
|
|
|