平方根的C语言实现(二) —— 手算平方根的原理

原文链接

 

一个函数从数学上来说可以有无数个函数列收敛于这个函数,那么程序逼近实现来说可以有无数种算法,平方根自然也不例外。

  不知道有多少人还记得手算平方根,那是满足每次在结果上添加一位,也就是按位逼近运算结果的唯一算法。至于数学上如何证明这个唯一性我就不说了,数学证明不会有那么多人有兴趣。按位逼近更加适合手算,举个大家更熟悉的例子,那就是手算除法。我这里就采用按位逼近的手算方法。

  要说手算平方根,原理其实非常简单,

  一是平方根函数是严格单调增函数,

  二就是以下这个恒等式满足

  (a*N+b)≡ (a*N)+ 2*a*b*N + b2

      ≡ (a*N)+ b * ((a*N) * 2 + b)

  我们实例操作一次平方根笔算,来解释一下。

  我们来求5499025的平方根。

  先将5499025两位两位从低往高排,为

  5 49 90 25

  2*2<5<3*3

  所以最高位为2,

  然后我们再来看549的平方根,

  我们假设549的平方根的整数部分是2*10+b,则根据之前的恒等式,N在这里等于10,a在这里等于2,有

  549 >=(2*10)+ 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)+ 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)+ 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

        -------------------

         |  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

之后,我们就可以用构建利用此算法的平方根了。

 

posted @ 2018-03-21 12:44  通宵敲代码  阅读(1524)  评论(0编辑  收藏  举报