简体   繁体   中英

BigDecimal output does not contain precise decimal values?

Practice problem using BigDecimal for the first time. My main method output should be:

Area of circle with radius 8.5949958is: 232.081671383290563028029402608911005665488497019210725540793500930304148269265220664195247142820189371870652494944664567810832522809505462646484375

Area of circle with radius 3.440393959403938E7is: 3718483500498323.66662697460176592346057689232315135847190735857072463126614392248114882022491656243801116943359375

however, that's not what is printed. I get a value of

232.081671383290555535978683110442943871021270751953125

for circle one, and a value of 3718483500498323.563695 for circle two. A colleague informed me that I need to use BigDecimals for every value in order to for the output to be precise, but I'm under the impression that I'm already doing this.

import java.math.BigDecimal;
public class Circle
{
private BigDecimal radius = new BigDecimal("0.0");

public Circle()
{
   setRadius(0.0);
} 
public void setRadius(double r)
{
   this.radius = new BigDecimal(r);
}
public BigDecimal findCircleArea(double radius)
{
  this.setRadius(radius);
  BigDecimal Pi = new BigDecimal("3.14159");
  BigDecimal rad = new BigDecimal(Math.pow(radius, 2.0));
  BigDecimal a = Pi.multiply(rad);

  return a;
}

}

Merge if you need to, but I've looked around and haven't been able to find an answer, it's really frustrating me.

I think you have misunderstanding of your task or you missed something in input data. I can prove it easy on mathematical basis.

Consider you first example: on input you have value equal to 8.5949958 . Even without doing multiplication this number on itself (square) we can estimate maximum number of digits in its fractional part: it can not be more then 14 digits, because 10^-7 * 10^-7 = 10^-14 . If we will take it as BigDecimal value and square it, we receive:

BigDecimal rad = BigDecimal.valueOf(radius).pow(2);

=73.87395280201764 which exact value of square of given input. Ie there is no lose of precision here.

Going next step. Next you multiply this number on 3.14159 . Again, using same approach we can estimate maximum number of digits in meaningful fractional part: it can not be more than 19 digits, because 10^-5 * 10^-14 = 10^-19 . Let's do this multiplication:

BigDecimal a = Pi.multiply(rad);

=232.0816713832905976476 - 19 digits. So we didn't lose any precision here.

From what follows that this long numbers which you expect on output simply can not be received for given input. Or you miss something in input, or this is a mistake in task.

To get all those digits of precision, you need to transform double values to BigDecimals as soon as possible, since double values, being inexact, contain “hidden” extra digits that will contribute to the scale of the result. Avoid the use of Strings and do not do any double math.

Essentially, change this:

BigDecimal Pi = new BigDecimal("3.14159");
BigDecimal rad = new BigDecimal(Math.pow(radius, 2.0));

to this:

BigDecimal Pi = new BigDecimal(3.14159);
BigDecimal rad = new BigDecimal(radius).pow(2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM