Round up problem when restricting Digits after Decimal point.

Hi,

I am trying to restrict digits after deicmal point using BigDecimal. I want to restrict it to 4 digits after decimal point and while doing this i want the 4th digit to roundup depending on 5th digit.

For this i'm using following code.

BigDecimal bd = new BigDecimal(num);

bd = bd.setScale(4,BigDecimal.ROUND_UP);

When i set num = 7.8213 it gives bd = 7.8213 and when i set num = 7.821300000000001 it givesbd = 7.8214 where as it must give 7.8213 as all digits after 4th decimal place are less than 5.

If i use code,

BigDecimal bd = new BigDecimal(num);

bd = bd.setScale(4,BigDecimal.ROUND_HALF_UP);

then the above problem is solved, but now if I set num = 1.20345 it gives bd = 1.2034 and when i set num = 1.2034500000000001 it gives bd = 1.2035.

Please suggest me code to implement simple universal roundup rule i.e. to round up a number upto a decimal place, add 1 to digit at that decimal place if digit at next decimal place is greater than 5 else keep it as it is.

Thanks,

Sachin Patil

[1074 byte] By [SachinPatila] at [2007-11-27 10:55:04]
# 1

That is because you probably used BigDecimal's double constructor.double num = 1.20345;

System.out.println(new BigDecimal(num)); // unscaled value

System.out.println(new BigDecimal(num).setScale(4, BigDecimal.ROUND_HALF_UP));

System.out.println(new BigDecimal("1.20345").setScale(4, BigDecimal.ROUND_HALF_UP));

gives the following result:

1.20344999999999990869525845482712611556053161621094

1.2034

1.2035

This issue is explicitly discussed in the BigDecimal documentation for the double constructor:

"Translates a double into a BigDecimal. The scale of the BigDecimal is the smallest value such that (10scale * val) is an integer.

Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.

The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. "

TimTheEnchantora at 2007-7-29 11:54:03 > top of Java-index,Java Essentials,Java Programming...
# 2

Hey thanks man. Thanks a lot for the info.

SachinPatila at 2007-7-29 11:54:03 > top of Java-index,Java Essentials,Java Programming...