Java Math.pow(a,b)时间复杂度

时间:2015-09-05 23:53:28

标签: java time-complexity

我想问下面代码的时间复杂度。是O(n)? (Math.pow()的时间复杂度是否为O(1)?)一般来说,Math.pow(a,b)是否具有时间复杂度O(b)或O(1)?提前谢谢。

public void foo(int[] ar) {
   int n = ar.length;
   int sum = 0;
   for(int i = 0; i < n; ++i) {

     sum += Math.pow(10,ar[i]);

   }
}

2 个答案:

答案 0 :(得分:7)

@Blindy讨论了Java在实施pow时可能采用的可能的方法。

首先,一般情况不能重复乘法。它对于指数不是整数的一般情况不起作用。 (pow的签名是Math.pow(double, double)!)

在OpenJDK 8代码库中,pow的本机代码实现可以通过两种方式工作:

  • e_pow.c中的第一个实现使用幂级数。该方法在C评论中描述如下:

    * Method:  Let x =  2   * (1+f)
    *      1. Compute and return log2(x) in two pieces:
    *              log2(x) = w1 + w2,
    *         where w1 has 53-24 = 29 bit trailing zeros.
    *      2. Perform y*log2(x) = n+y' by simulating multi-precision
    *         arithmetic, where |y'|<=0.5.
    *      3. Return x**y = 2**n*exp(y'*log2)
    
  • w_pow.c中的第二个实现是标准C库提供的pow函数的包装器。包装器处理边缘情况。

现在标准C库可能使用CPU特定的数学指令。如果确实如此,并且JDK构建(或运行时)选择 1 第二个实现,那么Java也会使用这些指令。

但不管怎样,我看不到任何使用重复乘法的特殊情况代码的痕迹。您可以放心地假设它是O(1)

1 - 我没有深入研究何时/可以进行选择。

答案 1 :(得分:6)

您可以将Math.pow视为O(1)。

有一些可能的实现,从CPU汇编程序指令(Java不使用它)到稳定的软件实现,基于(例如)Taylor系列扩展的几个术语(尽管不完全是Taylor实现,还有一些更具体的算法。)

如果你担心的话,绝对不会反复增加。