1
2
3
4
5
6
7
8
9
|
版權申明:本文爲博主窗戶(Colin Cai)原創,歡迎轉帖。如要轉貼,必須註明原文網址
http://www.cnblogs.com/Colin-Cai/p/7220506.html
做者:窗戶
QQ:6679072
E-mail:6679072@qq.com
|
一個函數從數學上來講能夠有無數個函數列收斂於這個函數,那麼程序逼近實現來講能夠有無數種算法,平方根天然也不例外。html
不知道有多少人還記得手算平方根,那是知足每次在結果上添加一位,也就是按位逼近運算結果的惟一算法。至於數學上如何證實這個惟一性我就不說了,數學證實不會有那麼多人有興趣。按位逼近更加適合手算,舉個你們更熟悉的例子,那就是手算除法。我這裏就採用按位逼近的手算方法。算法
要說手算平方根,原理其實很是簡單,sql
一是平方根函數是嚴格單調增函數,函數
二就是如下這個恆等式知足post
(a*N+b)2 ≡ (a*N)2 + 2*a*b*N + b2spa
≡ (a*N)2 + b * ((a*N) * 2 + b)設計
咱們實例操做一次平方根筆算,來解釋一下。code
咱們來求5499025的平方根。htm
先將5499025兩位兩位從低往高排,爲blog
5 49 90 25
2*2<5<3*3
因此最高位爲2,
而後咱們再來看549的平方根,
咱們假設549的平方根的整數部分是2*10+b,則根據以前的恆等式,N在這裏等於10,a在這裏等於2,有
549 >=(2*10)2 + b * ((2*10) * 2 + b)
整理一下,149 >= b * (40 + b)
3 * 43 < 149 < 4 * 44
因此b=3,
549的平方根整數部分是23,
再假設54990的平方根整數部分爲23*10+b,
則
54990 >= (23*10)2 + b * ((23*10) * 2 + b)
整理一下,2090 >= b * (460 + b),
464 * 4 < 2090 < 465 * 5
因此b=4,
54990的平方根整數部分爲234,
最後再來看5499025的平方根的整數部分,假設爲234 * 10 + b,
則
5499025 >= (234*10)2 + b * ((234*10) * 2 + b)
整理一下, 23425 >= b * (4680 + b)
而5 * 4685 = 23425, 等式成立,
因此最終咱們要求的平方根是2345。固然,小數位其實同樣能夠用這種方法繼續算下去。
手算平方根就是如上這樣從高位一步步往地位推的過程,寫成式子的形式大體以下:
2 3 4 5
-------------------
| 5 49 90 25
2 | 4
-------------------
| 1 49
43 | 1 29 ——當前算出了2,2*10*2 = 40 ,若是不懂能夠看前面(a*N+b)2的推導
-------------------
| 20 90
464 | 18 56 ——當前算出了23,23*10*2 = 460
-------------------
| 2 34 25
4685 | 2 34 25 ——當前算出了234,234*10*2 = 4680
-------------------
0
固然,如何寫不重要,知道過程即可以繼續咱們的這個設計。接下去咱們要去利用以前的這個算法,改裝一下,來進行二進制的開平方。
二進制的每一位不是1就是0,這樣在每次往前推一位的時候就相對簡單。
舉個例子,咱們來算121的平方根,也就是二進制下1111001的平方根。
兩位兩位從低位往高位排
1 0 1 1
------------------
| 1 11 10 01
1 | 1
------------------
| 11
100 | 0 ——當前上面算出了1,1右移動兩位爲100
------------------
| 11 10
1001 | 10 01 ——當前上面算出了10,1右移動兩位爲1000
------------------
| 1 01 01
10101 | 1 01 01 ——當前上面算出了101,1右移動兩位爲10100
------------------
0
每往右邊推1位,下面的除數就是上面當前算出來的二進制的數右移兩位再加1或者加0
以後,咱們就能夠用構建利用此算法的平方根了。