求平方根函数

<textarea cols="50" rows="15" name="code" class="cpp">加一点注释: unsigned short work( unsigned int n/*要进行开平方运算的对象*/ ) { unsigned int ans = 0;/*开平方运算的结果*/ unsigned int square = 0;/*记录中间产生的平方值*/ unsigned short r = 0;/*程序最终的返回结果*/ for ( int i = 15; i &gt;= 0; --i )/*整形的长度为4个字节,即32位,这里取15为30的一半,够用了*/ { unsigned int tmp = square;/*上次运算的平方值*/ tmp += (ans&lt;&lt;(i+1))+(1&lt;&lt;(i&lt;&lt;1)); /*tmp-ans的平方,(ans&lt;&lt;(i+1))-即2*(ans&lt;&lt;i)=2 * ans * (1 &lt;&lt;i),(1&lt;&lt;(i&lt;&lt;1))-即(1 &lt;&lt;i)的平方, 即整个式子含义是(ans+(1 &lt;&lt;i))的平方赋给tmp*/ if ( tmp &lt;= n )/*生成的平方值如果大于被开方的数n,显然应该被舍弃*/ { square = tmp;/*记录本次循环的平方值*/ ans |= 1&lt;&lt;i;/*生成开平方结果*/ } } r |= ans;/*留下需要的位,返回开平方结果*/ return r; }</textarea>

 

<textarea cols="50" rows="15" name="code" class="cpp">unsigned short work( unsigned int n ) {/*这个可能容易理解一些*/ unsigned int ans = 0; unsigned int square = 0; unsigned short r = 0; unsigned int tmp = 0; for ( int i = 15; i &gt;= 0; --i ) { tmp += (ans&lt;&lt;(i+1))+(1&lt;&lt;(i&lt;&lt;1)); if ( tmp &lt;= n ) { square = tmp; ans |= 1&lt;&lt;i; }else tmp = square; } r |= ans; return r; }</textarea>

 

<textarea cols="50" rows="15" name="code" class="cpp">unsigned short work( unsigned int n ) { unsigned int ans = 0; unsigned int square = 0; unsigned short r = 0; for ( int i = 15; i &gt;= 0; --i ) { unsigned int tmp = square; tmp += (ans&lt;&lt;(i+1))+(1&lt;&lt;(i&lt;&lt;1)); if ( tmp &lt;= n ) { square = tmp; ans |= 1&lt;&lt;i; } } r |= ans; return r; }</textarea>

 

<textarea cols="50" rows="15" name="code" class="cpp">/*------------------------------------------------------------------------------ 2 3写出以你所可能实现的最高效率的函数,用于将一个unsigned int数开平方。如果被求的数 4不是完全平方数,求出它的平方根的整数部分。尽你所可能的优化它的效率,并用文字证 5明你优化策略有效。 6函数的声明为: 7unsigned short work(unsigned int n); 8 9 10天地之灵 20:14:35 11巧妙运用二进制上的特征,以及合并运算,可以省略掉乘法和除法 12天地之灵 20:15:21 13首先,与其理解为二分查找,还不如理解为,在二进制层面上,从前向后决定每一个二进制位上是0还是1 14天地之灵 20:16:06 15因此,我们可以从最高位向最低位,依次上1,看乘积结果是否大于目标数,如果大于目标数了,那一位就保留0 16天地之灵 20:17:24 17这样的情况下,我们上1就不用真的去计算乘法,而是将之前的结果,加上上1以前的数左移1所在位置那么多位的两倍(相当于多左移一位),再加上上1的位置左移上1的位置 18wtthappy 20:17:52 19消化一下 20天地之灵 20:17:57 21好 22wtthappy 20:19:59 23最后一段不太明白什么意思? 24天地之灵 20:20:55 25 11000000 26 11000000 27________________ 281001000000000000 29天地之灵 20:22:02 30 11100000 31 11100000 32________________ 331001000000000000 340011000000000000 350000010000000000 36---------------- 371100010000000000 38天地之灵 20:22:58 39第一行是增加一个1之前乘的结果,第二行是增加1之前的数,左移1所在位+1的结果(也就是左移6位) 40第三行是1所在位,再左移所在位的结果 41天地之灵 20:23:20 42和平方公式(a+b)^2 = a^2+a*b*2+ b^2 43天地之灵 20:23:48 44a = 11000000 45b = 00100000 46*2相当于多左移一位 47 48------------------------------------------------------------------------------*/ 49 50unsigned short work( unsigned int n ) 51{ 52 unsigned int ans = 0; 53 unsigned int square = 0; 54 unsigned short r = 0; 55 for ( int i = 15; i &gt;= 0; --i ) 56 { 57 unsigned int tmp = square; 58 tmp += (ans&lt;&lt;(i+1))+(1&lt;&lt;(i&lt;&lt;1)); 59 if ( tmp &lt;= n ) 60 { 61 square = tmp; 62 ans |= 1&lt;&lt;i; 63 } 64 } 65 r |= ans; 66 return r; 67} </textarea>

 

加一点注释:

unsigned short work( unsigned int n/*要进行开平方运算的对象*/ )
{
         unsigned int ans = 0;/*开平方运算的结果*/
         unsigned int square = 0;/*记录中间产生的平方值*/
         unsigned short r = 0;/*程序最终的返回结果*/
         for ( int i = 15; i >= 0; --i )/*整形的长度为4个字节,即32位,这里取15为30的一半,够用了*/
         {
             unsigned int tmp = square;/*上次运算的平方值*/
             tmp += (ans<<(i+1))+(1<<(i<<1));

/*tmp-ans的平方,(ans<<(i+1))-即2*(ans<<i)=2 * ans * (1 <<i),(1<<(i<<1))-即(1 <<i)的平方,

即整个式子含义是(ans+(1 <<i))的平方赋给tmp*/
             if ( tmp <= n )/*生成的平方值如果大于被开方的数n,显然应该被舍弃*/
             {
                  square = tmp;/*记录本次循环的平方值*/
                  ans |= 1<<i;/*生成开平方结果*/
             }
         }
         r |= ans;/*留下需要的位,返回开平方结果*/
         return r;
}

 

这样写的算法核心思想是做二进制的处理,即选择每一位上是1还是0,实际上是一种搜索算法。

你可能感兴趣的:(优化,算法)