計算機如何實現開根號?

九茶發表於2015-05-20

今天看到一個問題:計算機如何實現開根號?

如何求一個數字的算術平方根(又叫開根號,或者開方)? 大家普遍都是用計算器直接計算的,對於程式設計師來說,就是呼叫sqrt()方法。但是其內部又是怎麼實現的呢?下面作了下總結。

———-

方法一:迭代法

學過計算方法的應該都還有印象:一個函式 f(x) 在區間 [a,b] 上連續,且 f(x)=0 在 x∈[a,b] 上有解,求x?
最簡單的就是用二分法:分別求f(a)、f(b)、f[(a+b)/2],哪兩個乘積為負數則把那兩個區間當做 [a,b] ,然後一直迴圈,直到 a-b 達到要求的精度為止。
再有一種就是用迭代法:迭代法有很多種,公共的思想是選一個數值,然後不斷迴圈迭代,讓它逐漸逼近真實解。至於怎麼迭代可以讓它趨近真實解,不同問題的求解用的迭代方法不同,我們暫且先忽略。
其實二分法也算是迭代法的一種了。

好了,直接看開根號的迭代法程式碼吧:

double _sqrt(double a)
{
    double x1 = a;
    double x2 = a/2;
    while(fabs(x1-x2) > 0.00000001)
    {
        x1 = x2;
        x2 = (x1+a/x1)/2;     ///////迭代的核心程式碼
    }
    return x1;
}


方法二:數學推導

用計算機設計演算法解決問題時,特別是數學問題,最直觀的思路有兩個。
一個是利用計算機強大的計算能力,用窮舉、遞迴、迭代等方法,直接求解,或者不斷趨近、收斂於真實解。例如有些密碼的破解,例如線性方程組的求解等等。
另外一種就是利用數學,把問題用數學推導簡化成一條公式,再通過計算機求解這條公式即可。最典型的就是圓周率Pi的計算公式:π/4=1-1/3+1/5-1/7+1/9-1/11+……

百度裡面有一個求開方的很好的方法,原址見此
這裡寫圖片描述
以上方法可以筆算求解出任意一個正數的算術平方根。可是為什麼要乘以20呢?為什麼a要這樣試驗得到呢?這些數學原理我們不用深究,畢竟我們的目的不是搞數學研究。
我們的重點是,這應該怎樣轉化成程式程式碼呢?我的大約思路是:
1、用要求開方的這個數用字元陣列儲存,然後把它分隔成兩個兩個字元,用atoi函式轉成int型存在一個整型陣列裡邊,然後對這個整型陣列進行操作。這樣就能求任意長的數字的開方了,這是用第一種方法做不到的。
2、看上面的圖,暫且把193.9叫做商,把29、383、3869叫做除數。則:把商的每一位數存在int型陣列裡邊,則各個除數都能用商的各位數表示出來了。
3、邏輯實現:重點有兩個,一個是除法的實現,另外一個是小數的處理。
具體的程式碼就不放出來了。



以上兩種解法,只是解決了開根號的問題而已。我們注重的是求解思路,而不是具體的方法。畢竟生活中的問題不少,而解法又各式不同。但知道了從哪個方向去利用計算機開根號,那開立方、求對數 這些問題也就都容易解了。

生命不息,學習不止,以後如果還遇到其他解法,再來補上。


轉載請註明出處,謝謝!(原文連結:http://blog.csdn.net/bone_ace/article/details/45870975

相關文章