ApfloatMath.pow花了很多时间

时间:2018-04-28 02:35:06

标签: java bigdecimal logarithm apfloat

我必须找到日志,然后在几次计算之后找到许多大十进制数的反对数。由于BigDecimal数字不支持log和antilog,为此我使用了Apfloat库并使用它的pow方法,它可以将两个参数作为Apfloat值,如下所示:

ApfloatMath.pow(Constants.BASE_OF_LOG,apFloatNum);

问题是我在循环中使用它并且循环很大。 Apfloat pow需要花费大量时间才能找到超过一小时的功率。为了避免这种情况,我想到将Apfloat转换为double,然后使用Math.pow,它运行速度很快,但是给了我很少的值。

我该怎么办?有谁知道ApfloatMath.pow替代?

1 个答案:

答案 0 :(得分:0)

你说你现在正在使用Math.pow(),而且有些调用会返回无限值。

如果您可以使用(远不那么准确)doubles代替BigDecimals,那么您应该想到数学

这一事实
x = Math.pow(a, x);

相当于

x = Math.pow(a, x - y) * Math.pow(a, y);

假设你有一个很大的价值,我们称之为big,而不是做:

// pow(a, big) may return infinite
BigDecimal n = BigDecimal.valueOf(Math.pow(a, big));

你也可以这样做:

// do this once, outside the loop
BigDecimal large = BigDecimal.valueOf(a).pow(100);

...

    // do this inside the loop
    // pow(a, big - 100) should not return infinite
    BigDecimal n = BigDecimal.valueOf(Math.pow(a, big - 100)).multiply(large);

而不是100,您可能想要选择另一个更适合您正在使用的值的常量。但是像上面的这样的东西可以是一个简单的解决方案,并且比你描述的要快得多。

注意

对于大值,ApfloatMath.pow()可能只会慢一些。如果是这种情况,您也可以将上述原则应用于Apfloat.pow()。您只需要在循环外执行以下一次

Apfloat large = ApfloatMath.pow(Constants.BASE_OF_LOG, 100); 

然后你可以在循环中使用以下

x = ApfloatMath.pow(Constants.BASE_OF_LOG, big - 100).multiply(large);

在循环中。

但你必须测试是否能让事情变得更快。我可以想象,对于整数指数,ApfloatMath.pow()可以快得多。

由于我对您的数据了解不多,而且我没有安装Apfloat,因此我无法对此进行测试,因此您应该看看上述解决方案是否足够好你(特别是如果它足够准确),如果它实际上比你的更好/更快。