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
以后,咱们就能够用构建利用此算法的平方根了。