aspose file tools*
The moose likes Beginning Java and the fly likes Rounding Doubles to Two Decimal Places Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Rounding Doubles to Two Decimal Places" Watch "Rounding Doubles to Two Decimal Places" New topic
Author

Rounding Doubles to Two Decimal Places

David Dickinson
Ranch Hand

Joined: Nov 11, 2004
Posts: 66
Hi All,

I've searched the archive and found a few different posts regarding restricting the number of decimal places in doubles. However they all suggest different methods, BigDecimal, NumberFormat etc.

Which is the simplest method of rounding a number say 10.023445656 to 10.02?

Thanks
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272


Mike Gershman
SCJP 1.4, SCWCD in process
Joyce Lee
Ranch Hand

Joined: Jul 11, 2003
Posts: 1392
Hi David,

How about this?



Joyce
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Originally posted by Joyce Lee:
How about this?


No, that's not a good way to do it. The reason is that floating-point arithmetic ("double" is a floating-point type) is not exact. So you're quite likely to end up printing something like 10.020000000000001 or 10.0199999999999 .

NumberFormat is probably the way to go. Alternatively, you could switch to using integers, where arithmetic is exact. Obviously, that would involve rescaling your values, as you can't have fractions.

Currency calculations are an example. Beginners often do currency calculations in floating-point, because they work in dollars, pounds or euros, which have a fractional part - the number of cents or pence. Instead, such calculations should be done in cents or pence, by integers. When printing out, use the divide (/100) and modulus (%100) integer operations to get the number of dollars/pounds/euros and cents/pence respectively.

HTH


Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
David Dickinson
Ranch Hand

Joined: Nov 11, 2004
Posts: 66
Hi,

Is there no way to round the double but keep the the value stored as a double?

I'm running JUnit tests and want to compare the computed result with the result I have calculated manually which is stored to two decimal points?

Thanks
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
why not "Math.abs( myValue - yourValue ) <= 0.005"?
David Dickinson
Ranch Hand

Joined: Nov 11, 2004
Posts: 66
If I can't find a more elegant solution to the problem then thats an option Mike.

This doesn't seem like a big problem to me surely Java has some function which automatically rounds a number when a precision of 2 is required?

Thanks all, hopefully i'll get a solution soon
Joyce Lee
Ranch Hand

Joined: Jul 11, 2003
Posts: 1392
Originally posted by Peter Chase:

No, that's not a good way to do it. The reason is that floating-point arithmetic ("double" is a floating-point type) is not exact. So you're quite likely to end up printing something like 10.020000000000001 or 10.0199999999999 .

Peter, I printed the output using the Math.round approach. But it didn't end up printing like 10.020000000000001 or 10.0199999999999. I may have missed out something. Could you give a value that would end up something like that? Thanks.
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
You could do this:


I should warn you that the result may be inexact by one or two low-order bits.
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Since you are using JUnit, there is no reason to round. Instead, you should use Assert.assertEquals(double expected, double actual, double precision) to compare the two numbers. The last parameter indicates the accuracy of your comparison. For example, you can do something like

To assert that your calculated value is within 1/100 th of the manually derived value.

For more details about the methods available in the Assert class (and other JUnit classes, you should consult the JUnit javadocs. They come with the JUnit distribution.

HTH

Layne
[ November 19, 2004: Message edited by: Layne Lund ]

Java API Documentation
The Java Tutorial
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Joyce Lee:

Peter, I printed the output using the Math.round approach. But it didn't end up printing like 10.020000000000001 or 10.0199999999999. I may have missed out something. Could you give a value that would end up something like that? Thanks.

I think this was an illustrative example. Results can vary between machines. The point is that floating point arithmetic is not exact because of the limitations of storing fractions in a computer. This is very analogous to writing one-third (1/3) as a decimal. Depending on how accurate you want to be, this fraction can be written as 0.33 or 0.3333, but no matter what you do, there is no exact decimal equivalent to 1/3. Similar situations arise with floating point numbers stored in binary. I won't get into the details here because it has been discussed several times before. If you are interested in the details, you can use the Saloon's search tool or google for more information.

Layne
David Dickinson
Ranch Hand

Joined: Nov 11, 2004
Posts: 66
Layne,

Indeed your right I have always set my Delta (the allowable difference between the two numbers under evaluation) to 0 to ensure accuracy. But this would be the simplest way of doing things.

That old saying "I can't see for things for looking at them" springs to mind

Thank you!
Joyce Lee
Ranch Hand

Joined: Jul 11, 2003
Posts: 1392
I still don't get the idea why using Math.round approach would end up 10.020000000000001 or 10.0199999999999. I did a quick search in this forum. Here are the threads that recommended using Math.round approach to round off to 2 decimal places. Did I miss out anything?

Thread 1
Thread 2
Thread 3
Thread 4
Thread 5
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by David Dickinson:
Layne,

Indeed your right I have always set my Delta (the allowable difference between the two numbers under evaluation) to 0 to ensure accuracy. But this would be the simplest way of doing things.

That old saying "I can't see for things for looking at them" springs to mind

Thank you!

As you probably see, you shouldn't rely on comparing doubles for equalit (which is essentially the same as setting your delta to 0.0 in this case). The reasons are related to another reply I will post next, so stay tuned.

Layne
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Joyce Lee:
I still don't get the idea why using Math.round approach would end up 10.020000000000001 or 10.0199999999999. I did a quick search in this forum. Here are the threads that recommended using Math.round approach to round off to 2 decimal places. Did I miss out anything?

Thread 1
Thread 2
Thread 3
Thread 4
Thread 5

The problem isn't with Math.round(); it's with doing arithmetic on the result that is returned from this method! The problem here stems from how most modern computers store floating point numbers (double is a floating-point number). This thread gives a basic explanation of the issues involved here. For more technical details, you need to look at the IEEE standard that is mentioned in the last message of the thread. (Take a look here for more information about IEEE 754 standard. Although it doesn't give details about the issues discussed here, the concpets discussed are necessary to understand the implications of floating-point arithmetic.)

HTH

Layne
[ November 19, 2004: Message edited by: Layne Lund ]
Joyce Lee
Ranch Hand

Joined: Jul 11, 2003
Posts: 1392
Originally posted by Layne Lund:

The problem isn't with Math.round(); it's with doing arithmetic on the result that is returned from this method!


I wasn't talking about Math.round(). I was referring to Math.round approach, meaning Math.round(100 * x) / 100d as a whole.

I would appreciate if someone could give a value of x that would result in something like this 10.020000000000001 instead of two decimal places using the formula above. I tested it on Window platform. I couldn't reproduce this problem as claimed. Thanks.
[ November 19, 2004: Message edited by: Joyce Lee ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Rounding Doubles to Two Decimal Places