2013-02-28 69 views
4

运行我的代码工作,但有时等我,我得到这个错误:递归算法来计算平方根,立方根

Exception in thread "main" java.lang.StackOverflowError  
at squareroot.SquareRoot.GetSquareRoot (SquareRoot.java: 9) 
at squareroot.SquareRoot.GetSquareRoot (SquareRoot.java: 13) 
at squareroot.SquareRoot.GetSquareRoot (SquareRoot.java: 13)` 

我检查我的代码,我不进入无限循环,请我该如何解决这个问题?谢谢。

public static double GetSquareRoot(double n, double low, double high) { 
    double sqrt = (low + high)/2; 
    if (sqrt*sqrt > n) 
     return GetSquareRoot(n, low, sqrt); 
    if (sqrt*sqrt < n) 
     return GetSquareRoot(n, sqrt, high); 
    return sqrt; 
} 
public static double Sqrt(double n){ 
    return GetSquareRoot(n, 0, n); 
} 

public static double GetCubicRoot(double n, double low, double high) { 
    double cbrt = (low + high)/2; 
    if (cbrt*cbrt*cbrt > n) 
     return GetCubicRoot(n, low, cbrt); 
    if (cbrt*cbrt*cbrt < n) 
     return GetCubicRoot(n, cbrt, high); 
    return cbrt; 
} 
public static double Cbrt(double n) { 
    return GetCubicRoot(n, 0, n); 
} 

public static void main(String[] args) { 
    Scanner Input = new Scanner(System.in); 

    double n = Input.nextDouble(); 
    double sqrt = Sqrt(n); 
    double cbrt = Cbrt(n); 

    System.out.println("Raiz cuadrada igual a: "+ sqrt);   
    System.out.println("Raiz cubica igual a: "+ cbrt); 

} 
+1

因为浮点比较并不精确,所以您可能要近似比较'sqrt * sqrt == n'。 – dchhetri 2013-02-28 22:52:33

回答

10

您的结果不会永远可能击中结束条件,因为相乘的数字是不可能产生的确切数量,你必须引入的误差幅度,因为平方根通常不准确和浮动算术使用因近似浮点限制。

public static double GetSquareRoot(double n, double low, double high) { 
    double errorMargin = 0.001;   
    double sqrt = (low + high)/2; 
    double diff = sqrt*sqrt - n; 
    if (diff > errorMargin) 
     return GetSquareRoot(n, low, sqrt); 
    if (-diff > errorMargin) 
     return GetSquareRoot(n, sqrt, high); 
    return sqrt; 
} 
6

你停止的条件是“如果n == num”而n和num是双倍的。已知双数或浮点数是不准确的,所以这个条件可能永远不会被满足。取而代之的是使用这个

if(Math.abs(sqrt*sqrt - n) < .001) 
    return sqrt; 

当两个数字之间的差异“足够小”时,这将停止。

5

当您使用double时,应该使用delta double值。因为你的计算值可能不像你期望的那样相等。

bool CompareDoubles2 (double A, double B) 
{ 
    diff = A - B; 
    return (diff < EPSILON) && (-diff > EPSILON); 
}