• Post Reply Bookmark Topic Watch Topic
  • New Topic

Question regarding the BigDecimal class  RSS feed

 
andy kumar
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply.

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
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you all for responding to my questions, my doubt is cleared now.
 
andy kumar
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The printout for a double may be rounded.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!