2016-09-16 16 views
0

我需要編寫一個函數來爲課程分配計算平方數。它可以計算像16和25個數字的平方根,但不準確地計算出的9我的平方根函數並不能爲某些數字提供準確的結果

平方根下面是代碼

double mysqrt (double x) 
{ 
    double low, high, mid; 

這個if語句決定創建了一個範圍,以確定的平方根。

if (x >= 0) { 

     low = 0; 
     high = x; 

    } 
    else { 

    low = x; 
    high = 1; 

    } 

該語句計算的中間值

mid = (high + low)/2.0; 

while循環用於確定平方根。

while (abs(mid*mid - x) > 0.0001) 
    { 

     if (mid * mid > x) 
      high = mid; 

     else 
      low = mid; 

     mid = (high/2.0) + (low/2.0); 
    } 

    return mid; 
} 
+0

任何不使用[std :: sqrt](http://en.cppreference.com/w/cpp/numeric/math/sqrt)函數的原因? – 2016-09-16 23:13:41

+2

老師可能會對使用std :: sqrt執行二分搜索的任務感到fr fr不安。 –

+0

'不準確地計算9的平方根'定義*精確*「。這是浮點數,所以絕對不會有100%的準確性。此外,你的循環以'0.0001'打破,這比雙打的精度還差。 – dxiv

回答

1

通常情況下,我不只是做別人的功課他們,但我想挑戰的想法,融合應該始終靠在固定小量值進行比較的錯誤檢測。

記住的double數據類型,只能代表從有限範圍獲得的值,所以比較兩個結果之間等價可用於檢測收斂,其中以任意精度這樣做可能會導致無限迭代

另外,一組可能的浮點值是分佈式的,因此對於較小的值而言,一個值與下一個較大的值之間的差值小於大值,因此如果使用epsilon,通常不適合保留它固定在一些任意「小」值。

下面的代碼執行相同的啞二進制搜索,但退出條件測試重新訪問以前的迭代結果,這意味着進一步的迭代將只是永遠覆蓋相同的搜索狀態,並且錯誤是接近的儘可能最小化。

以這種方式,ε是由double數據類型自身以及輸入自動確定的。如果用某種任意精度類代替double,那麼你確實需要提供一個epsilon,否則非理性的根可能會循環,直到某種失敗,如內存不足的情況。

#include <iostream> 
#include <iomanip> 

double mysqrt(double x) { 
    double low, high; 
    if(x < 1) { 
     if(x <= 0) return 0; 
     low = x; 
     high = 1; 
    } else { 
     low = 1; 
     high = x; 
    } 
    for(;;) { 
     const double mid = (low + high)/2; 
     if(high == mid || low == mid) return mid; 
     if(mid * mid > x) { 
      high = mid; 
     } else { 
      low = mid; 
     } 
    } 
} 

int main() { 
    std::cout << std::setprecision(14) << mysqrt(3) << '\n'; 
} 
+0

+1'挑戰這樣的觀點,即應該總是通過比較針對固定epsilon值的錯誤。對於一個挑逗,'mid * mid'可能會溢出* *非常*大'x'。如果在 dxiv

+1

好的一點,我對此做了很少的測試,但是我確實看到了x == 0的不好的情況,所以我只是把它與負輸入檢測結合在一起。我同意'如果(mid> x/mid)...'可能是更好的方法,但我想讓事情接近OP的原始代碼。 –

相關問題