This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes Java in General and the fly likes Rounding Numbers Down / Truncating Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Rounding Numbers Down / Truncating" Watch "Rounding Numbers Down / Truncating" New topic
Author

Rounding Numbers Down / Truncating

Phil Lewis
Greenhorn

Joined: Apr 01, 2003
Posts: 4
I am currently writing a currency programme where the numbers need to be rounded down as the bank would do. Eg: 1234.56789 would become 1234.56 not 1234.57
What is the easiest/best way of achieving this?
Thanks
Phil
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Java performs proper rounding when converting to integer, so this would work:
((int)(amount * 100 - 50))/100.0
If, on the other hand, you prefer something more readable,
Math.floor(amount * 100) / 100
Would work just as well
- Peter
Arun Boraiah
Ranch Hand

Joined: Nov 28, 2001
Posts: 233
Try this as well
double d = Math.round( (1234.56565 * 100) )/100
-arun


Sharing is learning
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
That won't round down...
- Peter
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
How about this:
double d = (int)(1234.56565 * 100) / 100.0;


Java API Documentation
The Java Tutorial
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[PdH]: Java performs proper rounding when converting to integer
I wouldn't call that "proper rounding" - but it is what Phil asked for, based on the bank's requirement. Proper rounding is what's given by Math.round(), not Math.floor().
[ April 01, 2003: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Jim Yingst:
I wouldn't call that "proper rounding"
When Java converts a double (or float) to integer? Why not? The end result of my ((int)(amount * 100 - 50))/100.0 is not proper, of course -- that's what the "- 50" is about. But, AFAIK, the JVM cast to int uses proper rounding.
- Peter
[ April 02, 2003: Message edited by: Peter den Haan ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Nope, it doesn't.

Only the last line prints 2 - all the others print 1. Which is just wrong for anyone from a science/engineering background (non-CS that is), which is probably why you figured the behaviour would be otherwise. But that's what we're stuck with in Java, due to backwards compatibility with C and IEEE 754. The relevant spec is here:
Otherwise, if the floating-point number is not an infinity, the floating-point value is rounded to an integer value V, rounding toward zero using IEEE 754 round-toward-zero mode (�4.2.3).

Incidentally the Python language also inherited C-like integer division, but they're in the process of getting rid of it. See here for details.
[ April 02, 2003: Message edited by: Jim Yingst ]
[ April 02, 2003: Message edited by: Jim Yingst ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I note that even if Java did perform proper rounding on an (int) cast, this wouldn't work:
((int)(amount * 100 - 50))/100.0
Should be
((int)(amount * 100 - 0.5))/100.0
(Again, if Java did proper rounding.)
However the alternate solution
Math.floor(amount * 100) / 100
works fine, as does Layne's
double d = (int)(amount * 100) / 100.0;
(which was also how I would've answered.)
[ April 02, 2003: Message edited by: Jim Yingst ]
Denise Hum
Greenhorn

Joined: Oct 09, 2001
Posts: 20
Another thing you could try would be to use java.math.BigDecimal, particularly since you are dealing with currency.
double d = 1234.56789;
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(2, BigDecimal.ROUND_DOWN);
This would give you 1234.56.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Jim, d'oh. You are, of course, entirely right. The conversion to int does not perform proper rounding, and of course you'd have to use 0.5 if it did. Oh well. Yesterday was not my best day on the 'ranch anyway.
Let's see this as a vivid demonstration why using Math.floor() and friends is a good idea.
- Peter
[ April 03, 2003: Message edited by: Peter den Haan ]
Phil Lewis
Greenhorn

Joined: Apr 01, 2003
Posts: 4
Many thanks for all your help guys.
As some of you pointed out, this is a strange request as 1.99999999 is clearly nearer 2 than 1, but apparently this is how the banks work it - gotta get every penny out of you!!
I eventually used the ((int)*100)/100.
This seemed to work, but after rounding down 4 different amounts and adding them together a strange thing happened.
The amounts added together were 20.74, 5.00, 5.00, 5.00. This should have totalled 35.74, but instead it came back with 35.73!! Can't understand it. I tried it with just the first 3 calculations and it came back with 30.74 - which is right!
As I said . . . WEIRD! I shall persevere
Thanks again though
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Sounds very strange. Are you sure that the four numbers you were adding were really the rounded values, or is it possible that you were displaying rounded values while addingun-rounded values? If you can create a reasonably short code sample which demonstrates the problem, that would be good.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Rounding Numbers Down / Truncating