This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes Money and digits problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Money and digits problem" Watch "Money and digits problem" New topic
Author

Money and digits problem

Tyson Lindner
Ranch Hand

Joined: May 16, 2012
Posts: 172
I'm writing a program that does some simple math problems on user inputted dollar amounts. I'm currently using double for those amounts.

Sometimes, the user might enter 7.25 and 2.20, in which case, if its subtraction I need my output to be 5.05, but for larger numbers like 15,000 and 3000 I want my output to be "12,000" not "12,000.00". Is there an easy way around this or would I have to check my numbers and adjust the format every time?
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11161
    
  16

Tyson Lindner wrote:I'm writing a program that does some simple math problems on user inputted dollar amounts. I'm currently using double for those amounts.

That is a mistake. Money comes in discrete units, therefore you should use an integer type. In the U.S., the atomic unit would be cents, so the user input should be converted to pennies and all computations done that way with integer arithmetic. Otherwise, you will start finding weird rounding errors.


There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

As for the formatting of "larger" versus "non-larger" numbers: Yes, you're going to have to write code which says "If X is a larger number then format it this way, otherwise format it that way".
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

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.
Tyson Lindner
Ranch Hand

Joined: May 16, 2012
Posts: 172
Thanks for the replies, i'll definitely convert to int but just a quick follow up question:

The user input will still be double, is there a way to check how specific the input is? That way if the user puts in "125" I can have one print format, if its "125.75" I can have another, and if its "125.12352" I can print an error message.

I think I'll just scrap the idea of format depending on the size of the number, I don't really care if large numbers have the decimal places if that's how the user inputted them.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

Tyson Lindner wrote:The user input will still be double, is there a way to check how specific the input is? That way if the user puts in "125" I can have one print format, if its "125.75" I can have another, and if its "125.12352" I can print an error message.


No! The user input is not double. The user input is a String. its a String that may have look like: "125.12" or "125.12352"
It is never a double. The user input may also look like "12S.L2" where there is an S and a L instead of the proper digits 5 and 1 (one). It can look like "125.12 125.12"

You have to process/parse the user's input, see if it makes sense, and use it or give an error message.
Tyson Lindner
Ranch Hand

Joined: May 16, 2012
Posts: 172
Pat Farrell wrote:
Tyson Lindner wrote:The user input will still be double, is there a way to check how specific the input is? That way if the user puts in "125" I can have one print format, if its "125.75" I can have another, and if its "125.12352" I can print an error message.


No! The user input is not double. The user input is a String. its a String that may have look like: "125.12" or "125.12352"
It is never a double. The user input may also look like "12S.L2" where there is an S and a L instead of the proper digits 5 and 1 (one). It can look like "125.12 125.12"

You have to process/parse the user's input, see if it makes sense, and use it or give an error message.


Yeah I was parsing the string using Double.parseDouble() and catching a NumberFormatException, but 12.24523 is bad input for my purposes but won't throw an exception, so I'm wondering how I catch that.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60789
    
  65

I'll second Pat on that. For no purposes at all should double or float ever be used for money. Ever.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

Tyson Lindner wrote:Yeah I was parsing the string using Double.parseDouble() and catching a NumberFormatException, but 12.24523 is bad input for my purposes but won't throw an exception, so I'm wondering how I catch that.


Very bad to parse with .parseDouble(), as you'll be tempted to use the result. Plus, as you say, it doesn't catch a number of frequently occurring real world errors.

The standard approach is to use the Pattern and Matcher classes to process a regular expression. This also allows you to accept and ignore commas in the number. Sadly, its a bit complex to get the regex exactly right, you can get it close with a few minutes of effort, but getting it exact for all cases is a lot of effort.
Tyson Lindner
Ranch Hand

Joined: May 16, 2012
Posts: 172
Jeff Verdegan wrote:
Pat Farrell wrote:Never use float or double for money.

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.


Yeah I'm currently trying to figure this out. I can convert the double to int, but now I'm having trouble finding a way to print the integer back out with decimal places (if needed) in a JLabel. I suppose I can convert back to double and figure out how formatting works for JLabel which is something I was going to have to do anyway.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Tyson Lindner wrote:
Jeff Verdegan wrote:
Pat Farrell wrote:Never use float or double for money.

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.


Yeah I'm currently trying to figure this out. I can convert the double to int,


You won't convert double to int. If you take that approach, you'll only use int (or long). You'll never use double at all. Instead of storing and calculating in dollars, you'll do it in pennies. Then, when you want to display it in dollars, you'll have to convert your int to a String, and insert a decimal point before the last two digits (and also insert a leading zero if the int value is less than 10). [EDIT: Or use format() as Pat shows a couple posts further down. I had a total brain f**t thinking we couldn't do that. It's cleaner that way, but make sure you understand what it's doing and why it works if you decide to use it.]

but now I'm having trouble finding a way to print the integer back out with decimal places (if needed) in a JLabel.


See above.

I suppose I can convert back to double


No, that totally defeats the purpose of using ints in the first place.
Pat Farrell
Rancher

Joined: Aug 11, 2007
Posts: 4646
    
    5

Tyson Lindner wrote:Yeah I'm currently trying to figure this out. I can convert the double to int, but now I'm having trouble finding a way to print the integer back out with decimal places (if needed) in a JLabel. I suppose I can convert back to double and figure out how formatting works for JLabel which is something I was going to have to do anyway.


No, never double.

You want code like:



Tyson Lindner
Ranch Hand

Joined: May 16, 2012
Posts: 172
Pat Farrell wrote:
The standard approach is to use the Pattern and Matcher classes to process a regular expression. This also allows you to accept and ignore commas in the number. Sadly, its a bit complex to get the regex exactly right, you can get it close with a few minutes of effort, but getting it exact for all cases is a lot of effort.


Thanks, I guess I'll have to look into these although I wish there was an easier way.
 
wood burning stoves
 
subject: Money and digits problem
 
Similar Threads
Program: Change Due/Tendered
opinion poll: readability
Formatted output - any ideas?
Is Composite pattern appropriate ?
Plain help