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


      版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址
    
      http://www.cnblogs.com/Colin-Cai/p/7220506.html 
    
      作者:窗户
    
      QQ:6679072
    
      E-mail:6679072@qq.com
    

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

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

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

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

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

      (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

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

  • 相关阅读:
    HTTP 状态码
    Buffer 流文件
    事件(Event)机制 .on() .emit() .once() .removeListener()
    UDP node客户端和服务端
    node全局变量  node定时器 系统自带的模块 http服务器
    标题省略,不会自动换行
    SpringBoot 出现 Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
    循环对象
    npm
    根据对象的key值,查找对应的属性value
  • 原文地址:https://www.cnblogs.com/Colin-Cai/p/7220506.html
Copyright © 2020-2023  润新知