【问题标题】:How to deal with exact precision in Java?如何处理Java中的精确精度?
【发布时间】:2019-05-22 15:37:14
【问题描述】:

要求是检查位于二维平面中的特定点是否通过特定线。

给出的 2 个缩写点是 (3,1)(12, 3)。 直线的斜率可以计算为

(y2-y1) / (x2-x1)

然后可以使用y = mx + c 构造线的方程 其中 m 是斜率,c 是常数。 表示线的方程是2x + 3 = 9y

所以,要检查上面的线是否经过坐标(-6, -1),我们只需检查 2x + 3 = 9y

2x + 3 = 2(-6) + 3 = -12 + 3 = -9 = 9(-1) -> true

这在处理笔和纸时很容易。

但是,当斜率计算为 (3-1)/(12-3) = 2/9 时,java 中的精度会丢失

使用 Bigdecimal,在计算斜率时会出现异常

java.lang.ArithmeticException:非终止十进制扩展;没有精确可表示的十进制结果。

和双

    double slope = (double)(3-1)/(double)(12-3);  //0.2222222222222222
    // Putting (3,1) to get c
    double c = (double)(1) - (double)(slope * 3); //0.33333333333333337
    Hence the equation of the line is y = 0.2222222222222222(x) + 0.33333333333333337

    // to check whether (-6, -1) passes through the above line, put the x coordinate 
    double yCoordinate = 0.2222222222222222* (-6) + 0.33333333333333337;

y坐标是-0.9999999999999999,不是-1。所以结果是错误的,但通过简单的数学计算得出的答案是正确的。我怎样才能得到预期的结果?

【问题讨论】:

  • 检查结果是否在预期结果的小增量内。要阻止ArithmeticExceptionBigDecimal 抛出,您必须使用适当的MathContext
  • 您可以使用提供分数支持的库,例如Apache Commons Math
  • 如果你使用 org.junit.Assert.assertEquals(double expected, double actual, double delta) 会怎样? (junit.sourceforge.net/javadoc/org/junit/…)
  • 您可以使用这个 Assert.assertEquals() 将结果与所需的精度进行比较。例如。 Assert.assertEquals(-1, -0.9999999999, 0.0001)

标签: java double precision bigdecimal


【解决方案1】:

这已经足够接近给出一个准确的值,但不是正确的方式

public double getExactValueDiv(double a,double b){
      double tmp = a/b;
      tmp=Math.round(tmp*1000000000)/1000000000
      return tmp;
}

【讨论】:

    猜你喜欢
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 2016-04-30
    • 1970-01-01
    • 2014-01-19
    • 2022-01-20
    相关资源
    最近更新 更多