高效开平方

 1/*------------------------------------------------------------------------------
 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 >= 0--i )
56         {
57             unsigned int tmp = square;
58             tmp += (ans<<(i+1))+(1<<(i<<1));
59             if ( tmp <= n )
60             {
61                  square = tmp;
62                  ans |= 1<<i;
63             }

64         }

65         r |= ans;
66         return r;
67}

68
posted @ 2008-06-23 23:13  王婷婷๑→‿ฺ←๑  阅读(1461)  评论(0编辑  收藏  举报