| 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: 18652
|
|
[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: 18652
|
|
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: 18652
|
|
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: 18652
|
|
|
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.
|
 |
 |
|
|
subject: Rounding Numbers Down / Truncating
|
|
|