1
/*------------------------------------------------------------------------------
2
3
写出以你所可能实现的最高效率的函数,用于将一个unsigned int数开平方。如果被求的数
4
不是完全平方数,求出它的平方根的整数部分。尽你所可能的优化它的效率,并用文字证
5
明你优化策略有效。
6
函数的声明为:
7
unsigned 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的位置
18
wtthappy 20:17:52
19
消化一下
20
天地之灵 20:17:57
21
好
22
wtthappy 20:19:59
23
最后一段不太明白什么意思?
24
天地之灵 20:20:55
25
11000000
26
11000000
27
________________
28
1001000000000000
29
天地之灵 20:22:02
30
11100000
31
11100000
32
________________
33
1001000000000000
34
0011000000000000
35
0000010000000000
36
----------------
37
1100010000000000
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
44
a = 11000000
45
b = 00100000
46
*2相当于多左移一位
47
48
------------------------------------------------------------------------------*/
49
50
unsigned 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
/*------------------------------------------------------------------------------2

3
写出以你所可能实现的最高效率的函数,用于将一个unsigned int数开平方。如果被求的数4
不是完全平方数,求出它的平方根的整数部分。尽你所可能的优化它的效率,并用文字证5
明你优化策略有效。6
函数的声明为:7
unsigned short work(unsigned int n);8

9

10
天地之灵 20:14:3511
巧妙运用二进制上的特征,以及合并运算,可以省略掉乘法和除法12
天地之灵 20:15:2113
首先,与其理解为二分查找,还不如理解为,在二进制层面上,从前向后决定每一个二进制位上是0还是114
天地之灵 20:16:0615
因此,我们可以从最高位向最低位,依次上1,看乘积结果是否大于目标数,如果大于目标数了,那一位就保留016
天地之灵 20:17:2417
这样的情况下,我们上1就不用真的去计算乘法,而是将之前的结果,加上上1以前的数左移1所在位置那么多位的两倍(相当于多左移一位),再加上上1的位置左移上1的位置18
wtthappy 20:17:5219
消化一下20
天地之灵 20:17:5721
好22
wtthappy 20:19:5923
最后一段不太明白什么意思?24
天地之灵 20:20:5525
1100000026
1100000027
________________28
100100000000000029
天地之灵 20:22:0230
1110000031
1110000032
________________33
100100000000000034
001100000000000035
000001000000000036
----------------37
110001000000000038
天地之灵 20:22:5839
第一行是增加一个1之前乘的结果,第二行是增加1之前的数,左移1所在位+1的结果(也就是左移6位)40
第三行是1所在位,再左移所在位的结果41
天地之灵 20:23:2042
和平方公式(a+b)^2 = a^2+a*b*2+ b^243
天地之灵 20:23:4844
a = 1100000045
b = 0010000046
*2相当于多左移一位47

48
------------------------------------------------------------------------------*/49

50
unsigned 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


