数值的整数次方

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

自以为题目简单的解法:用for或者while循环

double Poweruint(double a, unsigned int ex)
{
	double ret = 1.0;
	while (ex--){
		ret *= a;
	}
	return ret;
}

 可是这个程序只包括了指数是正数的情况,指数是负数和零的时候怎么办?我们都知道,

  1. 任何非零数的零次方为1,0的0次方没有意义,因此输出0或1都是可以接受的。
  2. 指数为负数时,先对指数求绝对值,然后算出次方的结果再求倒数。
  3. 底数为0,指数为负数时,要对0求倒数会导致程序运行出错,因此要做特殊处理,可以采用三种方法:返回值,全局代码和异常。    这个题的解法中我们采用了全局变量来标识是否出错,如果出错则返回0值。为了区分返回的0值是输出结果还是出错处理,再定义一个变量flag,初始化为0,如果是出错导致结果输出为0则令flag=1来标识。
  4. 计算机表示小数都有误差,我们不能直接用等号(==)判断,要使两个数的差值在一个精度内。

在考虑了指数的各种情况后,我们可以考虑优化次方函数,如输入的指数为32,在for循环中需要做31次乘法。但我们可以换一种思路:

目标次数是32,如果知道了它的16次方,那么在16次方基础上平方就可以了。而16次方是8次方的平方,以此类推,求32次方只需要做5次乘法:先求平方,再平方基础上求4次方,4次方基础上求8次方,8次方基础上求16次方,16次方,基础上求32次方。 

可以用下面的公式求解:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int equal(double a, double b)//比较两个浮点数是否相等
{
	if ((a - b) > -0.000001 && (a - b) < 0.000001){
		return 1;
	}
	else{
		return 0;
	}
}
double Poweruint1(double a, unsigned int ex)//低效率
{
	double ret = 1.0;
	//for (unsigned int i = 0; i <= ex; i++){
	//	ret *= a;
	//}
	while (ex--){
		ret *= a;
	}
	return ret;
}
double Poweruint2(double a, unsigned int n)//位运算效率比乘除法和求余运算高
{
	if (0 == n){
		return 1.0;
	}
	if (1 == n){
		return a;
	}
	double ret =  Poweruint2(a, n >> 1);
	//double ret = Poweruint2(a, n/2);
	ret *= ret;
	if (1 == (n & 1)){
		ret *= a;
	}
	//if (1 == (n % 2)){
	//	ret *= a;
	//}
	return ret;
}
double Power(double base, int exponent)
{
	int flag = 0;
	double result = 1.0;
	unsigned int ex = (unsigned int)exponent;
	if (equal(base, 0.0) && exponent < 0){//底数为0并且指数小于0
		flag = 1;
		return 0.0;
	}
	if (exponent < 0){//指数为负数时先转化为正数
		ex = (unsigned int)(-exponent);
	}
	/*result = Poweruint1(base, ex);*/
	result = Poweruint2(base, ex);
	if (exponent < 0){
		result = 1.0 / result;
	}
	return result;
}
int main()
{
	double result = Power(0,0);
	printf("%f\n", result);
	system("pause");
	return 0;
}

 

要计算整数整数次方可以使用暴力求解或者使用二分法。下面是两种方法的示例代码: 方法一:暴力求解 ```c++ class Solution { public: double Power(double base, int exponent) { bool isFu = false; if(exponent < 0) { exponent *= (-1); isFu = true; } double res = 1; for(int i = 0; i < exponent; i++) { res *= base; } if(isFu) return 1/res; return res; } }; ``` 方法二:使用二分法 ```c++ class Solution { public: double Power(double base, int exponent) { bool isFu = false; // 判断是否为负数次方根 if(exponent < 0) { exponent *= (-1); isFu = true; } bool isStrange = false; // 判断是否为奇数 if(exponent % 2 != 0) { isStrange = true; exponent -= 1; } int count = 0; // 记录除2次数 while(exponent != 0 && exponent % 2 == 0) { count++; exponent /= 2; } double res = 1; // 记录结果 // 该情况exponent一开始为奇数,比如7,那么7-1 = 6,6/2 = 3,即不管如何都应该进行3次暴力乘法 for(int i = 0; i < exponent; i++) { res *= base; } // 通过记录的count次数,本身*本身即可。 for(int i = 0; i < count; i++) { res *= res; } // 如果为奇数,还应该进行一次乘法 if(isStrange) { res *= base; } // 如果为负数次方根 if(isFu) return 1/res; return res; } }; ``` 以上就是两种计算整数次方的方法,可以根据具体需求选择合适的方法进行计算。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [数值整数次方(C++)](https://blog.csdn.net/qq135595696/article/details/125091372)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值