【面试题11】数值的整数次方

【题目描述】

实现函数 double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同事不需要考虑大数问题。

【解决方案】

1. 自以为题目很简单的解法

1         public static double Power(double baseNum, int exponent)
2         {
3             double result = 1.0;
4             for (int i = 0; i < exponent; i++)
5             {
6                 result *= baseNum;
7             }
8             return result;
9         }

2. 全面但不够高效的解法,我们离Offer已经很近了

需要考虑的特殊情况:

a. 底数为0的0次方没有意义,无论输出0还是1都是可以接受的,这需要和面试官说清楚,以证明你考虑到边界值的情况;

b. 指数为负数时,需要先进行乘方,然后求倒;

c. 针对0的负数次方,先乘方,再求倒,会对0求倒,应该针对这种情况做兼容;

d. 错误处理采用什么方式?返回值,全局代码,还是异常?

综合以上特殊情况,可以写出下面代码,仅供参考:

 1         public static double Power(double baseNum, int exponent)
 2         {
 3             double result = 1.0;
 4             bool isPositive = true;
 5 
 6             if (Equal(baseNum, 0.0) && (exponent < 0))
 7             {
 8                 throw new Exception("Invalid Input.");
 9             }
10 
11             if (exponent < 0)
12             {
13                 isPositive = false;
14                 exponent = -exponent;
15             }
16 
17             result = PowerWithPositiveExponent(baseNum, exponent);
18 
19             if (!isPositive)
20             {
21                 result = 1.0 / result;
22             }
23 
24             return result;
25         }
26 
27         public static double PowerWithPositiveExponent(double baseNum, int exponent)
28         {
29             double result = 1.0;
30 
31             for (int i = 0; i < exponent; i++)
32             {
33                 result *= baseNum;
34             }
35 
36             return result;
37         }
38 
39         /// <summary>
40         /// 由于计算机表示小数(包括float和double型小数)都有误差,
41         /// 我们不能直接用等号(==)判断两个小数是否相等,
42         /// 如果两个小数的差的绝对值很小,比如小于0.0000001,
43         /// 就可以认为他们相等。
44         /// </summary>
45         /// <param name="num1"></param>
46         /// <param name="num2"></param>
47         /// <returns></returns>
48         public static bool Equal(double num1, double num2)
49         {
50             if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
51                 return true;
52             else
53                 return false;
54         }

3. 全面又高效的解法,确保我们能拿到Offer

如果面试官对效率要求很高,我们还可以继续优化:

a. 如果exponent为32,则我们需要做32次运算,我们可以换一种思路,如果我们知道了16次方那么只需要计算一次就可以了,想要知道16次方,需要知道8次方。

以此类推,可以得到如下公式,能减少运算的次数,提高效率,代码可以使用递归来实现,

b. 用位运算来替换普通的运算符,效率高很多,既然优化代码,就要把优化做到极致;

我的代码实现,仅供参考:

 1         public static double PowerWithPositiveExponent(double baseNum, int exponent)
 2         {
 3             if (exponent == 0)
 4                 return 1.0;
 5 
 6             if (exponent == 1)
 7                 return baseNum;
 8 
 9             double result = PowerWithPositiveExponent(baseNum, exponent >> 1);
10             result *= result;
11 
12             if ((exponent & 0x1) == 1)
13                 result *= baseNum;
14 
15             return result;
16         }

 

posted @ 2015-09-11 15:54  叫我霍啊啊啊  阅读(204)  评论(0编辑  收藏  举报