我有一个简单的BigDecimal,我想为另一个BigDecimal供电,例如11.11 ^ -1.54。在Java / Android中最好的方法是什么?我不喜欢转换为双打的想法,因为它是用于医疗应用,所以我很欣赏最大的可能性。到目前为止,我已经审核了Google Guava的http://commons.apache.org/math/和数学内容,但一无所获。
编辑: 整个计算很复杂,并且有很多这样的操作。我需要尽可能多的精确度。
答案 0 :(得分:8)
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 );
答案 1 :(得分:3)
您需要多少位数的精度?您的示例中仅使用4位数字。如果这是医学和现实世界,你只能测量现实世界中的大多数东西到10-13位精度,双倍精度可达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.
在您的设备上可能仍然足够快。
我没有包含代码,部分原因是它很长。我印象深刻的是它有多快。 ;)
答案 2 :(得分:3)
查看"Java Number Cruncher: The Java Programmer's Guide to Numerical Computing" - 第12.5章大十进制函数:有一些源代码尽可能精确地计算指数和对数的算法。
使用数学公式:x ^ y = exp(y * ln(x)),您可以获得最大精度的结果。
然而双打确实有很好的精确度,我强烈建议你测试一下它是否不够精确以满足你的需要。
答案 3 :(得分:2)
有一个很好的图书馆ApFloat:http://www.apfloat.org/