Pow(x, n) 求一个数的n次方

本文探讨了在C++中实现求幂函数pow的不同方法,包括简单的for循环、递归求解及其优化,并最终给出了一种高效利用位运算的算法。

我们知道C++中是有pow函数的,我们这次自己来写个,因为有这样的算法题目。

所需数学知识:

大致考虑正数,0,负数即可。n多个数相乘的问题。


1.简单For循环


这还不简单,马上写一个for循环:

double pow(double x, int n){
	int m = abs(n);
	double result = 1;
	for(int i = 0; i < m; ++i){
		result *= x;
	}
	return n > 0 ? result : 1/result;
}

2.最慢的递归求解


受 1+2+3+4+5...+N的问题用递归求解思路影响,我们知道这里可以用一个非常慢的递归来求解。


double pow(double x, int n){
    if(n == 0){
        return 1;
    }
    if(n > 0 ){
          return x * pow(x, n - 1);
     }else{
          return 1 /  pow(x, -n);
     }
    
}

搞不好比for循环还要慢。


3.很大改进的递归求解



都先考虑正数。我们在想,n多个2相乘,如果n刚好能被2整除,我们可以把n分成一半一半来考虑。

可以把它们想成是一半*一半,不能被2整除的话,也只是多乘以一个自己。

double pow(double x, int n){
	if(n == 0){
		return 1;
	}
       if(n > 0 ){
	    double half = pow(x, n / 2);
	    if(n % 2 == 0){
		return half * half;
	    }else{
		return half * half * x;
	    }			
	}else{
		return 1 /  pow(x, -n);
	}
}

我们知道这里的 n / 2,和 n % 2还可以用位运算来提高速度

n / 2 == n >> 1 (在返回是int值的情况下)

n % 2 == n&1

修改如下:


double pow(double x, int n){
	if(n == 0){
		return 1;
	}
       if(n > 0 ){
	    double half = pow(x, n >> 1);
	    if((n&1) == 0){
		return half * half;
	    }else{
		return half * half * x;
	    }			
	}else{
		return 1 /  pow(x, -n);
	}
}

4.当然还有优化空间!

3标题中我们其实做的事情是对n的每次取半再相加,这样太慢了,直接除以2比较快。当然遇到不能整除的要多乘以一个自己。

double pow(double x, int n){
	int m = abs(n);
	double result = 1;
	while(m > 0){
		if(m % 2 != 0){
			result = result * x;
		}
		x *= x;
		m = m / 2;
	}
	return n > 0 ? result : 1 / result;
}

通过位运算优化后就是:


double myPowFunction(double x, int n){
    int m = abs(n);
    double result = 1;
    while(m > 0){
        if((m&1) != 0){
            result = result * x;
        }
        x *= x;
        m >>= 1;
    }
    return n > 0 ? result : 1 / result;
}

看了下vs中的pow实现,也是类似的思想。

Pow(x, n) 求一个数的n次方


### C++ 中计算一个的 n 次方的方法 在 C++ 编程中,可以通过多种方式实现对某个其 n 次方的操作。以下是几种常见的方法: #### 方法一:使用循环结构 通过简单的 `for` 循环可以逐步累乘得到结果。这种方法适用于初学者理解基本逻辑。 ```cpp #include <iostream> using namespace std; int main() { int base, exponent; long long result = 1; // 使用long long防止溢出 cout << "请输入底和指: "; cin >> base >> exponent; for (int i = 0; i < exponent; ++i) { result *= base; } cout << base << "^" << exponent << "=" << result << endl; return 0; } ``` 此代码片段展示了如何利用循环来完成幂运算[^1]。 --- #### 方法二:递归函数调用 递归是一种优雅的方式用于解决重复性问题。下面是一个基于递归算法的例子: ```cpp #include <stdio.h> // 定义递归函数multi int multi(int a, int b); int main() { int a, b, c; printf("x=? n=?"); scanf("%d%d", &a, &b); c = multi(a, b); printf("%d**%d=%d\n", a, b, c); return 0; } int multi(int a, int b) { if (b == 0) return 1; // 基础情况处理 else if (b > 0) { return multi(a, b - 1) * a; // 递归调用 } return 1; } ``` 上述程序实现了 x 的 n 次方功能,并采用了标准输入输出流[^2]。 --- #### 方法三:借助 `<cmath>` 库中的 `pow()` 函数 C++ 提供了一个内置库函数 `pow(base, exp)` 来快速计算任意实的幂值。这是最简洁高效的办法之一。 ```cpp #include <iostream> #include <cmath> // 包含学头文件 using namespace std; int main() { double base, exponent; cout << "请输入底和指: "; cin >> base >> exponent; double result = pow(base, exponent); // 调用pow函数 cout << fixed; // 设置浮点精度显示模式 cout.precision(0); // 不保留小位 cout << base << "^" << exponent << "=" << result << endl; return 0; } ``` 这里演示了如何运用标准库函数简化复杂度较高的操作[^3]。 --- #### 方法四:位移运算符优化特定场景下的效率(仅限于基为2) 当需要特别针对 “2 的 N 次方” 这种特殊情形时,可考虑采用左移位运算代替传统乘法或调用其他工具包的做法,从而提升性能表现。 ```cpp #include <iostream> using namespace std; int main(){ unsigned int power; while(cin>>power){ unsigned int res=(1<<power); // 左移操作相当于连续加倍 cout<<res<<'\n'; } return 0; } ``` 该技术尤其适合处理涉及大量据集或者追极致速度的应用场合[^4]。 --- ### 总结 以上分别介绍了四种不同风格的技术路线——从基础教学型到高级技巧应用均有覆盖。开发者可以根据实际需灵活选用合适的方案解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值