为负指数产生错误结果的 power to n 实现

Power to n implementation that produces wrong results for negative exponent

pow(x, n) 方法的以下(天真)实现中,完全忽略任何优化方法,我发现以下问题:

public double pow(double x, int n) {  
  boolean negative = n < 0;  
  long power = Math.abs(n);  
  double ans = 1.0;  
  for(long i = 0; i < power; i++) {  
    ans = ans * x;  
  }    
  return negative ? 1.0/ans: ans;  
}  

这里我假设对于负指数的情况我简单地计算 x^n 然后 return 1/(x^n) 因为例如2^(-3) = 1/(2^3)

问题:
代码在以下情况下失败:
pow(2.00000, -2147483648)
输出是 1.00000 而预期的正确结果是 0.00000

如果我改代码如下:

public double pow(double x, int n) {  
  long power = n;  
  if(power < 0) {  
    x = 1 / x;  
    power = -power;
  }  
  double ans = 1.0;  
  for(long i = 0; i < power; i++) {  
    ans = ans * x;  
  }    
  return ans;  
}  

结果正确!

那么做这些方法有什么区别呢?我原以为它们是等效的,但它们不是

Math.abs(n)还是一个int,后来才赋给了一个long,所以-2147483648的绝对值是-2147483648再次(这在 the documentation of Math.abs(int) 中注明)。对于负边界,循环不执行迭代。

Math.abs((long)n) 可以解决这个问题。