简体   繁体   English

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

[英]BigDecimal output does not contain precise decimal values?

Practice problem using BigDecimal for the first time. 第一次使用BigDecimal练习问题。 My main method output should be: 我的主要方法输出应该是:

Area of circle with radius 8.5949958is: 232.081671383290563028029402608911005665488497019210725540793500930304148269265220664195247142820189371870652494944664567810832522809505462646484375 半径为8.5949958的圆的面积:232.081671383290563028029402608911005665488497019210725540793500930304148269265220664195247142820189371870652494944664567810832522809505462646484375

Area of circle with radius 3.440393959403938E7is: 3718483500498323.66662697460176592346057689232315135847190735857072463126614392248114882022491656243801116943359375 半径为3.440393959403938E7的圆的面积: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. 对于圆圈1,对于圆圈2,值为3718483500498323.563695 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. 一位同事告诉我,我需要为每个值使用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;
}

}

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 . 首先考虑你的例子:输入时你的值等于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 . 即使不对这个数字进行乘法(正方形),我们也可以估计其小数部分的最大位数:它不能超过14位数,因为10^-7 * 10^-7 = 10^-14 If we will take it as BigDecimal value and square it, we receive: 如果我们将它作为BigDecimal值并将其平方,我们会收到:

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

=73.87395280201764 which exact value of square of given input. =73.87395280201764给定输入的平方精确值。 Ie there is no lose of precision here. 也就是说,这里没有精度损失。

Going next step. 下一步。 Next you multiply this number on 3.14159 . 接下来,您将此数字乘以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 . 同样,使用相同的方法,我们可以估计有意义的小数部分中的最大位数:它不能超过19位,因为10^-5 * 10^-14 = 10^-19 Let's do this multiplication: 让我们做这个乘法:

BigDecimal a = Pi.multiply(rad);

=232.0816713832905976476 - 19 digits. =232.0816713832905976476 - 19位数。 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. 要获得所有这些精度数字,您需要尽快将double值转换为BigDecimals,因为不精确的double值包含“隐藏”的额外数字,这些数字将有助于结果的比例。 Avoid the use of Strings and do not do any double math. 避免使用字符串,不要做任何double数学运算。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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