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

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68
