使用ApFloat以特定精度进行舍入

时间:2016-10-21 00:41:33

标签: java rounding bigdecimal arbitrary-precision apfloat

ApFloat http://www.apfloat.org/是一个C / C ++ / Java数学库,可以计算许多trascendental操作,如平方根,取幂,对数,三角/双曲函数,π的数值等,具有任意精度的数字,BigDecimal Java类中没有。

我们都知道4/3的扩展是无限的:1.333 ....所以当我们试图以任何特定的精度得到它时,无论多长时间,都会有信息丢失,但四舍五入模式也很重要,即

  • 4/3,精度为5,地板舍入模式为1.3333
  • 4/3 with 精度为5,天花板舍入模式为1.3334

不幸的是,在执行这样的操作时不能指定舍入模式,可能是因为“由于在实现中可能发生的不同类型的舍入错误,对于任何方法都没有给出例如单调性的保证。”

但是,有一种方法可以使用特定的精度和舍入模式{Apler]来舍入ApFloat数字http://www.apfloat.org/apfloat_java/docs/org/apfloat/ApfloatMath.html#round-org.apfloat.Apfloat-long-java.math.RoundingMode-

一个简单的解决方案可能是以额外的精度计算操作,然后使用原始精度和所需的舍入模式舍入结果,如下例所示:

// Trying to get the square root of 2
// with precision of 10
// and different roundig modes

Apfloat two = new Apfloat(2, 15); // precision is 15, not 10
// result: 2

Apfloat sqrt = ApfloatMath.sqrt(two);
// result: 1.41421356237309

ApfloatMath.round(sqrt, 10, RoundingMode.FLOOR);
// result: 1.414213562

ApfloatMath.round(sqrt, 10, RoundingMode.CEILING);
// result: 1.414213563

问题是:

  • 这种方法[总是]是否正确?你知道任何反例或假阳性吗?
  • 1是要添加到精度中的最不必要的值,以便额外的信息确保正确的舍入?我认为在精度上加1是不够的,因为附加数字可能已经被用于执行计算的内部算法四舍五入。添加至少2个位置将确保第一个数字 - 正确到达所需的精度 - 将是数字的真实 - 无限值中存在的真实数字,而不是圆形数字。
  • 你意识到更好的方法吗?特别是避免两步的一个,因为类似Apfloat的BigDecimals是不可变的类,因此每个步骤都会创建新的实例,这在使用具有数千或数百个精确位置的数字时可能会有问题。

1 个答案:

答案 0 :(得分:0)

在这里,我希望有所帮助

public static void main(String[] args) {
    Apfloat two = new Apfloat(2, 15); // Line 1: If you want precision be 10, than you can´t get result 1.41421356237309 on Line 4, because result have more than 10 numbers after . (decimal dot)
                                      // you can add new Apfloat variable with precision 15 for line 4 and for line 5,6 with precision 10
    System.out.print("Line2: Expected: 2 Result:" + two + "\n"); // Line 2:
    Apfloat sqrt = ApfloatMath.sqrt(two); // Line 3:
    System.out.print("Line4: Expected: 1.41421356237309 Result:" + sqrt + "\n"); // Line 4:
    System.out.print("Line5: Expected: 1.414213562 Result:" + ApfloatMath.round(sqrt, 10, RoundingMode.FLOOR) + "\n"); // Line 5:
    System.out.print("Line6: Expected: 1.414213563 Result:" + ApfloatMath.round(sqrt, 10, RoundingMode.CEILING) + "\n"); // Line 6:
}

<强>结果:

enter image description here