programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering OS Languages Paradigms IDEs Build Tools Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# Question regarding the BigDecimal class

andy kumar
Ranch Hand
Posts: 64
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
Saloon Keeper
Posts: 3329
46
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
Posts: 64

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
Posts: 23295
125
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
Posts: 64
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
Saloon Keeper
Posts: 3329
46
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
Posts: 23295
125
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
Posts: 64
Thank you all for responding to my questions, my doubt is cleared now.

andy kumar
Ranch Hand
Posts: 64
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
Marshal
Posts: 56599
172
The printout for a double may be rounded.

 It is sorta covered in the JavaRanch Style Guide.