这有点模糊,但我需要一个可以非常快速地计算的函数,类似于^ b,其中a介于0和1之间,b非常大。对于许多b,它将一次计算一个a。理想情况下,结果将在0.4%以内。提前谢谢。
答案 0 :(得分:2)
将我的评论转化为答案:
既然你提到b
大到足以舍入为整数,那么一种方法就是通过平方来使用Binary Exponentiation algorithm。
Math.pow()
很慢,因为它需要处理非整数幂。因此,可以在您的情况下做得更好,因为您可以使用整数供电算法。
与往常一样,对您的实施进行基准测试,看它是否真的比Math.pow()
更快。
这是OP找到的实现:
public static double pow(double a, int b) {
double result = 1;
while(b > 0) {
if (b % 2 != 0) {
result *= a;
b--;
}
a *= a;
b /= 2;
}
return result;
}
这是我快速而肮脏(未经优化)的实施:
public static double intPow(double base,int pow){
int c = Integer.numberOfLeadingZeros(pow);
pow <<= c;
double value = 1;
for (; c < 32; c++){
value *= value;
if (pow < 0)
value *= base;
pow <<= 1;
}
return value;
}
这适用于所有积极的pow
。但我没有对Math.pow()
进行基准测试。
答案 1 :(得分:2)
对于您的具体情况(“为多个b计算一次a”),我建议采用以下方法:
准备稍后在特定计算中使用的表格数据:
确定N使得每个可能的b的2 ^ N小于b。
计算表t:t [n] = a ^(2 ^ n),每个n小于N.这有效地完成为t [k + 1] = t [k] * t [ K]
计算a ^ b:
这个想法是为不同的b重用a ^(2 ^ n)的值。
答案 2 :(得分:0)
Apache FastMath提供double pow(double d, int e)
函数。
implementation is based on Veltkamp's TwoProduct algorithm。用法类似于标准Math.pow
函数:
import org.apache.commons.math3.util.FastMath;
// ...
FastMath.pow(3.1417, 2);