8

我有一个简单的 BigDecimal,我想为另一个 BigDecimal 供电,例如 11.11^-1.54。在 Java/Android 中最简洁的方法是什么?我不喜欢转换为双打的想法,因为它是用于医疗应用的,所以我会很感激可能的最大精度。到目前为止,我已经查看了来自 Google Guava 的http://commons.apache.org/math/和数学资料,但一无所获。

编辑:整个计算很复杂,并且有很多这样的操作。最后我需要尽可能多的精确度。

4

4 回答 4

9

BigDecimal 的实用程序类https://github.com/tareknaj/BigFunctions

z = x^y --> z = exp ( ln(x) * y ) 的示例

final int SCALE = 10;
BigDecimal x = new BigDecimal(1);
BigDecimal y = new BigDecimal(12);

BigDecimal z = BigFunctions.exp( BigFunctions.ln(x, SCALE).multiply(y),SCALE );
于 2014-03-21T10:29:22.283 回答
4

您需要多少位数的精度?您在示例中仅使用 4 位数字。如果这是医学上的并且适用于现实世界,那么您只能将现实世界中的大多数事物测量到 10-13 位的准确度,而 double 的准确度最高可以达到 16 位。

System.out.println(Math.pow(11.11, -1.54));

印刷

0.024524510581710988

如果您使用本书http://www.apropos-logic.com/nc/中的库,您可以获得

int runs = 10000;

long start = System.nanoTime();
double x1 = 0;
for (int i = 0; i < runs; i++)
    x1 = Math.pow(11.11, -1.54);
long time = System.nanoTime() - start;
System.out.println(x1 + " took " + time / runs / 1e3 + " us avg.");

long start2 = System.nanoTime();
BigDecimal x2 = null;
for (int i = 0; i < runs; i++)
    x2 = exp(ln(BigDecimal.valueOf(11.11), 20).multiply(BigDecimal.valueOf(-1.54)), 20);
long time2 = System.nanoTime() - start2;
System.out.println(x2 + " took " + time2 / runs / 1e3 + " us avg.");

打印(我们为微秒)

0.024524510581710988 took 0.478 us avg.
0.02452451058171098739 took 603.769 us avg.

40位精度

0.0245245105817109873886495555036930857940 took 1409 us avg.

在您的设备上可能仍然足够快。

我没有包含代码,部分原因是它很长。我对它的速度印象深刻。;)

于 2012-08-07T15:14:31.923 回答
3

查看“Java Number Cruncher: The Java Programmer's Guide to Numerical Computing” - 第 12.5 章 Big Decimal Functions:有一些源代码具有尽可能精确的算法来计算指数和对数。

使用数学公式: x^y=exp(y*ln(x)) 您可以获得最高精度的结果。

尽管如此,双打确实具有良好的精度,我强烈建议您测试它是否不够精确以满足您的需要。

于 2012-08-07T15:27:10.067 回答
2

有一个很好的库 ApFloat: http: //www.apfloat.org/

于 2013-01-16T17:18:04.903 回答