Big Moose Saloon
 Search | Java FAQ | Recent Topics Register / Login

# Question regarding the BigDecimal class

andy kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 49
HI All,

I have the below class definition:-

public class cal {

BigDecimal total = new BigDecimal("100");
BigDecimal percent1 = new BigDecimal("0.9");
BigDecimal percent2 = new BigDecimal(0.90);
BigDecimal percent3 = new BigDecimal(0.90f);

public static void main(String[] args){
cal c = new cal();
System.out.println(c.total.multiply(c.percent1));
System.out.println(c.total.multiply(c.percent2));
System.out.println(c.total.multiply(c.percent3));

}

Ouput:-

90.0
90.00000000000000222044604925031308084726333618164062500
89.99999761581420898437500

I am not able to understand why we have 2 different output for the same input.

Thanks
Carey Brown
Ranch Hand

Joined: Nov 19, 2001
Posts: 167

percent1 is 0.9 exactly
percent2 is the double representation of 0.9 which has a slight rounding error in the representation.
percent3 is the float representation of 0.9 which has a slight rounding error in the representation and has fewer decimal places than in percent2.
andy kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 49

But I thought since I am using BigDecimal class the answers in all the three cases should be exact to 90%, thats the whole reason of introducing the BigDecimal class.
I am asking this question as I have to implement a class that deals with numeric calculation involving % and all. So what would be the ideal way to initialize a BigDecimal object so as to get accurate results.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 17614

33

andy kumar wrote:
But I thought since I am using BigDecimal class the answers in all the three cases should be exact to 90%, thats the whole reason of introducing the BigDecimal class.

It is exact -- once the BigDecimal object was created. But in the case of float and double, the BigDecimal was created using variables that were not exact -- and BigDecimal did a good job at matching the non-exact numbers exactly.

If you want construct numbers that are exact, you will have to avoid floating point numbers -- either use strings, or use whole numbers and calculate to the specific value.

Henry

andy kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 49
Henry thanks for the response.

My app has calculation which involve decimal number so I cannot use whole number, so I guess I will have to go with the string representation. I have one last question if I declare a float like 0.9f how does it become 0.9888889.... shouldn't it be just 0.9 as I am explicitly declaring it to that value.

I think my main confusion is how does 0.9 convert to 0.9888...or o.90000002... when I have explicitly declared it o be 0.9.
Carey Brown
Ranch Hand

Joined: Nov 19, 2001
Posts: 167

Floating point numbers are stored internally in base-2 (ie binary). Not all base-10 numbers can be represented exactly in base-2 when they contain a fractional component (ie digits to the right of the decimal point).
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 17614

33

andy kumar wrote:I have one last question if I declare a float like 0.9f how does it become 0.9888889.... shouldn't it be just 0.9 as I am explicitly declaring it to that value.

I think my main confusion is how does 0.9 convert to 0.9888...or o.90000002... when I have explicitly declared it o be 0.9.

Keep in mind that the computer works in binary -- and this includes the power to be raised. The number 0.9 can easily be represented using whole numbers and base 10 -- ie. 9 x (10 ^ -1). Other the other hand, it is hard to find an X and Y, where X x (2^Y) = 0.9... And hence, the rounding error, for what seems to be obviously simple.

Henry

andy kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 49
Thank you all for responding to my questions, my doubt is cleared now.
andy kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 49
Hi,

I tried the below:-

Double x = new Double(0.9);
System.out.println(x);

output is 0.9.

Should it not be again "0.90000000000000002220446049250313080847263336181640625"?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 34529

13
The printout for a double may be rounded.

It is sorta covered in the JavaRanch Style Guide.

subject: Question regarding the BigDecimal class