Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!

# Rounding Numbers Down / Truncating

Phil Lewis
Greenhorn
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
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
Posts: 233
Try this as well
double d = Math.round( (1234.56565 * 100) )/100
-arun

Peter den Haan
author
Ranch Hand
Posts: 3252
That won't round down...
- Peter

Layne Lund
Ranch Hand
Posts: 3061
double d = (int)(1234.56565 * 100) / 100.0;

Jim Yingst
Wanderer
Sheriff
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 ]

Peter den Haan
author
Ranch Hand
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
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
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
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
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
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
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.