104 lines
2.2 KiB
Markdown
104 lines
2.2 KiB
Markdown
# 4.2 数值-指数
|
||
|
||
|
||
> 在a^n中,a叫做底数,n叫做指数。a^n读作“a的n次方”或“a的n次幂“
|
||
|
||
|
||
|
||
## 数值的整数次方
|
||
|
||
题目:实现函数`double Power(double base, int exponent)`,求base的exponent次方。
|
||
|
||
不需要考虑溢出。
|
||
|
||
分析:这是一道看起来很简单的问题。可能有不少的人在看到题目后30秒写出如下的代码:
|
||
```
|
||
double Power(double base, int exponent)
|
||
{
|
||
double result = 1.0;
|
||
for(int i = 1; i <= exponent; ++i)
|
||
result *= base;
|
||
return result;
|
||
}
|
||
```
|
||
|
||
|
||
上面的代码没有考虑: exponent<=0
|
||
判断一个浮点数是不是等于0时,不是直接写 base == 0 ,而应该判断它们的差的绝对值是不是小于一个很小的范围
|
||
|
||
如果指数大于0,我们还可以使用递归实现:`a^n = a^(n/2)*a^(n/2)` (n为偶数), 通过这个思路也可以实现
|
||
```
|
||
2^16 = 2^8 * 2^8
|
||
2^8 = 2^4 * 2^4
|
||
2^4 = 2^2 * 2^2
|
||
2^2 = 2^1 * 2^1
|
||
2^1 = 2
|
||
```
|
||
|
||
用例:
|
||
|
||
```
|
||
2 3 = 8
|
||
0 3 = 0
|
||
2 0 = 1
|
||
2 -3 = 1/(2^3) = 0.125
|
||
0 -3
|
||
```
|
||
|
||
使用递归实现的代码示例:
|
||
|
||
```
|
||
double Power(double base, unsigned int exponent)
|
||
{
|
||
if (exponent == 0) return 1;
|
||
if (exponent == 1) return base;
|
||
double result = Power(base, exponent >> 1);
|
||
result *= result;
|
||
|
||
if (exponent & 1) result = result*base;
|
||
|
||
return reslut;
|
||
}
|
||
```
|
||
|
||
|
||
## 求根号2的值
|
||
|
||
并且按照我的需要列出指定小数位,比如根号2是1.141 我要列出1位小数就是1.1 2位就是1.14, 1000位就是1.141...... 等。。
|
||
|
||
分析:
|
||
泰勒级数
|
||
牛顿迭代法
|
||
|
||
|
||
|
||
|
||
|
||
|
||
## 判断一个自然数是否是某个数的平方
|
||
|
||
说明:当然不能使用开方运算。
|
||
|
||
```
|
||
square(25) YES
|
||
square(35) NO
|
||
```
|
||
|
||
方法1: 从1开始遍历,显然这种方法很差
|
||
方法2: 除数跟余数比较,除数从2开始,每一轮都跟结果比较;相等就是存在这个数,不相等就把除数++;时间复杂度为(根号n)。在一个数比较大时,效率不够好。如1194877489 =(34567)^2,需要从2开始,一直比较到34566,做3万多次除法和比较运算。跟方法1一样。。
|
||
|
||
方法3:二分查找 O(logn)。比如25:
|
||
|
||
a. 先取(0+25)/2=12.5,12.5*12.5>25,因此这个数应该小于12.5
|
||
b.(0+12)/2 = 6, 6*6>25
|
||
c. (0+6)/2 = 3
|
||
d. (3+6)/2 = 4.5
|
||
e. (5+6)/2 = 5.5
|
||
|
||
```
|
||
int is_powered(int num)
|
||
```
|
||
|
||
|
||
|