2016-01-26 81 views
1

這是可以用來計算數字的平方根的公式。創建一個程序,可以在不使用Math.sqrt的情況下計算數字的平方根

result=(guess+(number/guess))/2; 

例如,我需要得到9的平方根。首先,我需要猜測。雖然,我知道9的平方根是3,但我選擇了6來顯示程序應該如何工作。

,使...

result=(6+(9/6))/2 which is equal to 3.75. 

要獲得9實際的平方根,我需要的結果,新guess.The方案應繼續作爲...

result=(3.75+(9/3.75))/2 which is equal to 3.075. 

此過程應繼續,直至結果與其等於0之後的結果之間的差值。例如,

result=(3+(9/3))/2 is always equal to 3. 

當結果的值傳遞給猜測時,下一個結果也將是3.這意味着3是9的平方根。

這裏是我的代碼:

package javaPackage; 

public class SquareRoot { 

    public static void main(String[] args) { 
     calcRoot(); 
    } 

    public static void calcRoot(){ 
     double num=9; 
     double guess=6; 
     double result=0; 

     while(Math.abs(guess-ans)!=0){ 
      result=(guess+(num/guess))/2;  
      guess=result; 
     } 
    System.out.print(result); 
    } 
} 

輸出

3.75 

我的問題是我不能比較結果的值和先前的結果。由於猜測等於結果,因此猜測和結果已經相同。我該如何解決它?

+1

什麼是變量'ans'? – SomeJavaGuy

+0

使用'Math.pow(num,0.5)'會有作弊嗎? – jsheeran

回答

3

只能兌換while循環的兩個語句(和初始化,從而避免被零除):

public static void calcRoot(){ 
    double num=9; 
    double guess=0; 
    double result=6; 

    while(Math.abs(guess-result)!=0){ 
     guess=result; 
     result=(guess+(num/guess))/2;  
    } 
System.out.print(result); 
} 

關鍵是要在guess舊值仍然在result當新一測試被執行。

而且你不應該測試!= 0,由於舍入誤差,這可能無法實現。更好地測試一些小值>= 1e-7

+0

我將它改爲> 0.000000,並在while循環中交換了兩個語句,但結果現在是無窮大。 –

+0

我也改變了初始值。 – Henry

+0

現在有效。我只需要了解你是如何做到的。謝謝! –

0

要將結果與以前的結果進行比較,您需要將它們都保存在變量中。

這是一個二元印章。

public static double sqrt(double ans) { 
    if (ans < 1) 
     return 1.0/sqrt(1.0/ans); 
    double guess = 1; 
    double add = ans/2; 
    while (add >= Math.ulp(guess)) { 
     double guess2 = guess + add; 
     double result = guess2 * guess2; 
     if (result < ans) 
      guess = guess2; 
     else if (result == ans) 
      return guess2; 
     add /= 2; 
    } 
    return guess; 
} 

public static void main(String[] args) { 
    for (int i = 0; i <= 10; i++) 
     System.out.println(sqrt(i) + " vs " + Math.sqrt(i)); 
} 

打印

0.0 vs 0.0 
1.0 vs 1.0 
1.414213562373095 vs 1.4142135623730951 
1.7320508075688772 vs 1.7320508075688772 
2.0 vs 2.0 
2.236067977499789 vs 2.23606797749979 
2.449489742783178 vs 2.449489742783178 
2.64575131106459 vs 2.6457513110645907 
2.82842712474619 vs 2.8284271247461903 
3.0 vs 3.0 
3.162277660168379 vs 3.1622776601683795 

for (int i = 0; i <= 10; i++) 
     System.out.println(i/10.0 + ": " + sqrt(i/10.0) + " vs " + Math.sqrt(i/10.0)); 

打印

0.0: 0.0 vs 0.0 
0.1: 0.31622776601683794 vs 0.31622776601683794 
0.2: 0.4472135954999581 vs 0.4472135954999579 
0.3: 0.5477225575051662 vs 0.5477225575051661 
0.4: 0.6324555320336759 vs 0.6324555320336759 
0.5: 0.7071067811865476 vs 0.7071067811865476 
0.6: 0.7745966692414834 vs 0.7745966692414834 
0.7: 0.8366600265340758 vs 0.8366600265340756 
0.8: 0.894427190999916 vs 0.8944271909999159 
0.9: 0.9486832980505138 vs 0.9486832980505138 
1.0: 1.0 vs 1.0 
0
public static double sqrt(double number) 
{ 
    double dd=number, sqi, sqrt=0; 
    long i, b=0, e=0, c=1, z, d=(long)number, r=0, j; 
    for (i=1l, sqi=1; ; i*=100l, sqi*=10) 
    { 
     if (i>dd) 
     { 
      i/=100; 
      sqi/=10; 
      j=i; 
      break; 
     } 
    } 
    for (z=0l; z<16; dd=(dd-(double)(r*i))*100, j/=100l, sqi/=10, z++) 
    { 
     r=(long)(dd/i); 
     d=(e*100l)+r; 
     int a=9; 
     for (c=((b*10l)+a)*a; ; a--) 
     { 
      c=((b*10l)+a)*a; 
      if (c<=d) 
       break; 
     } 
     //if (a>=0) 
     // System.out.print(a); 
     e=d-c; 
     sqrt+=a*sqi; 
     if (number==sqrt*sqrt && j==1) 
      break; 
     //if (j==1) 
     // System.out.print('.'); 
     b=b*10l+2l*(a); 
    } 
    return sqrt; 
} 

很抱歉的未定義variabl名字....但這個程序真的有用! 這個程序是基於發現平方根

0

只需創建另一個變量來存儲先前猜測的值長劃分方法。 這是代碼:

package javaPackage; 

public class SquareRoot { 

    public static void main(String[] args) { 
     calcRoot(); 
    } 

    public static void calcRoot(){ 
     double num=9; 
     double guess=6; 
     double prevGuess=0; 
     double result=0; 

     while(Math.abs(guess-prevGuess)!=0){ 
      result=(guess+(num/guess))/2; 
      prevGuess = guess; 
      guess=result; 
     } 
     System.out.print(result); 
    } 
} 
0

出於性能,下面這段代碼:

public static double sqrt(double num) { 
    double half = 0.5 * num; 
    long bit = Double.doubleToLongBits(num); 
    bit = 0x5fe6ec85e7de30daL - (bit >> 1); 
    num = Double.longBitsToDouble(bit); 

    for (int index = 0; index < 4; index++) { 
     num = num * (1.5f - half * num * num); 
    } 

    return 1/num; 
} 

關於magic0x5fe6ec85e7de30daL,你可以看到FAST INVERSE SQUARE ROOT 讓我們來看看性能,測試代碼:

double test = 123456; 

    //trigger the jit compiler 
    for (int index = 0; index < 100000000; index++) { 
     sqrt(test); 
    } 
    for (int index = 0; index < 100000000; index++) { 
     Math.sqrt(test); 
    } 


    //performance 
    long start = System.currentTimeMillis(); 
    for (long index = 0; index < 10000000000L; index++) { 
     sqrt(test); 
    } 
    System.out.println("this:"+(System.currentTimeMillis() - start)); 
    start = System.currentTimeMillis(); 
    for (long index = 0; index < 10000000000L; index++) { 
     Math.sqrt(test); 
    } 
    System.out.println("system:"+(System.currentTimeMillis() - start)); 


    System.out.println(sqrt(test)); 
    System.out.println(Math.sqrt(test)); 

,其結果是:

this:3327 
system:3236 
this result:351.363060095964 
system result:351.363060095964 
相關問題