0

ApFloat http://www.apfloat.org/是一个 C/C++/Java 数学库,可以计算平方根、指数、对数、三角/双曲函数、π 的数值等许多超越运算。任意精度,这在BigDecimalJava 类中不可用。

我们都知道 4/3 的展开是无限的:1.333....所以当我们试图以任何特定的精度得到它时,不管它有多长,都会有信息丢失,但是取整模式很重要,也就是

  • 4/3,精度为 5,地板舍入模式为 1.3333
  • 4/3,精度为 5,上限舍入模式为 1.3334

不幸的是,在执行此类操作时无法指定舍入模式,可能是因为“由于实现中可能出现不同类型的舍入错误,因此无法保证任何方法的单调性。”

但是,有一种方法可以使用特定的精度和舍入模式来舍入 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 - 是不可变的类,因此每一步都会创建新实例,这在使用具有数千或数百万个精度位置的数字时可能会出现问题。
4

1 回答 1

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

结果:

在此处输入图像描述

于 2016-10-21T16:07:27.177 回答