BigDecimal输出不包含精确的十进制值?

时间:2017-02-09 21:48:40

标签: java double precision bigdecimal autoboxing

第一次使用BigDecimal练习问题。 我的主要方法输出应该是:

  

半径为8.5949958的圆的面积:   232.081671383290563028029402608911005665488497019210725540793500930304148269265220664195247142820189371870652494944664567810832522809505462646484375

     

半径为3.440393959403938E7的圆的面积:   3718483500498323.66662697460176592346057689232315135847190735857072463126614392248114882022491656243801116943359375

然而,这不是印刷品。我得到了值

232.081671383290555535978683110442943871021270751953125

表示第一个圆圈,值3718483500498323.563695表示第二个圆圈。 一位同事告诉我,我需要为每个值使用BigDecimals才能使输出准确,但我的印象是我已经这样做了。

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;
}

}

如果你需要合并,但我环顾四周并且找不到答案,这真让我感到沮丧。

2 个答案:

答案 0 :(得分:0)

我认为您对您的任务有误解,或者您错过了输入数据中的某些内容。我可以在数学基础上证明这一点很容易。

首先考虑你的例子:在输入时你的价值等于8.5949958。即使没有对这个数字进行乘法(正方形),我们也可以估计其小数部分中的最大位数:它不能超过14个数字,因为10^-7 * 10^-7 = 10^-14。 如果我们将其视为BigDecimal值并将其平方,我们会收到:

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

=73.87395280201764给定输入的平方精确值。即这里没有精确度。

下一步。接下来,在3.14159上乘以此数字。同样,使用相同的方法,我们可以估计有意义的小数部分中的最大位数:它不能超过19个数字,因为10^-5 * 10^-14 = 10^-19。让我们做这个乘法:

BigDecimal a = Pi.multiply(rad);

=232.0816713832905976476 - 19位数。所以我们在这里没有失去任何精确度。

从下面的内容可以看出,对于给定的输入,您在输出上预期的长数字无法接收。或者你错过了输入内容,或者这是任务中的错误。

答案 1 :(得分:0)

要获得精度的所有这些数字,您需要尽快将double值转换为BigDecimals,因为double值不精确,包含“隐藏”的额外数字,这将有助于结果的规模。避免使用字符串,也不要进行任何double数学运算。

基本上,改变这个:

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

到此:

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