剑指offer-16:求数值的整数次方

这道题的题目为:实现函数double Power(double base,int n),求base的n次方,不得使用库函数。

对于这个问题,很容易就能写出下面的代码来求解:

#include<stdio.h>
#include<stdlib.h>
int Power(int base, int n)
{
	int result = 1;
	for (int i = 0; i < n; i++)
	{
		result *= base;
	}
	return result;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	printf("%d", Power(a, b));
	system("pause");
	return 0;
}

这种方法实现起来确实简单,但是它不够全面,有以下几点缺陷:
(1)没有考虑到指数为负数的情况;
(2)没有考虑到底数为0且指数是负数的情况,这种情况下就会出现对0求倒数,然后程序出错;

针对以上算法的缺陷,我做了如下改进,总结出了第二种算法:
(1)当指数为负数时,先对指数求绝对值,算出次方的结果后再求倒数;
(2)定义一个全局变量InvalidInput 来标记是否出错。出错时这个变量被设为true,否则false;

代码如下:

#include<stdio.h>
#include<stdlib.h>
bool InvalidInput = false;
double  PowerWithAbsn(double base, int absn)
{
	double result1 = 1.0;
	for (int i = 0; i <absn; i++)
	{
		result1 *= base;
	}
	return result1;
}
double Power(double base, int n)
{
	InvalidInput = false;
	int absn = 0;
	double result = 0;
	//底数为0且指数<=0
	if(base == 0.0&&n<=0)
	{
		InvalidInput = true;
		return 0.0;
	}
	//指数为负数
	else if (n < 0)
	{
	    absn = (-n);
		result = PowerWithAbsn(base, absn);
		if (n < 0)
			result = 1.0 / result;
		return result;
	}
	//指数为正数
	else
	{
		absn = n;
		result = PowerWithAbsn(base, absn);
		return result;
	}
}

int main()
{
	double a = 0.0;
	int b = 0;
	scanf("%lf %d", &a, &b);
	printf("%lf", Power(a, b));
	system("pause");
	return 0;
}

虽然第二种算法弥补了第一种算法的缺陷,但是它还不够完美,它的不足在于:如果输入的指数n为32,则函数 PowerWithAbsn的循环中需要计算31次。

所以针对第二种算法的缺陷,用总结出第三种算法,其思路可以概括如下:
求一个数字a的32次方,只需要在a的16次方再开方就可,以此类推只需要5 次乘方即可:(((((a)2)2)2)2)^2.
即以下面公式求a的n次方即可:
在这里插入图片描述
代码如下:

#include<stdio.h>
#include<stdlib.h>
bool InvalidInput = false;
double  PowerWithAbsn(double base, int absn)
{
	if (absn == 0)
	{
		return 1;
	}
	if (absn == 1)
	{
		return base;
	}
	double result1 = PowerWithAbsn(base, absn / 2);
	result1 *= result1;
	//判断n为偶数还是奇数
	if (absn % 2 == 1)
	{
		result1 = result1*base;
	}
	return result1;
}
double Power(double base, int n)
{
	InvalidInput = false;
	int absn = 0;
	double result = 0;
	//底数为0且指数<=0
	if (base == 0.0&&n <= 0)
	{
		InvalidInput = true;
		return 0.0;
	}
	//指数为负数
	else if (n < 0)
	{
		absn = (-n);
		result = PowerWithAbsn(base, absn);
		if (n < 0)
			result = 1.0 / result;
		return result;
	}
	//指数为正数
	else
	{
		absn = n;
		result = PowerWithAbsn(base, absn);
		return result;
	}
}

int main()
{
	double a = 0.0;
	int b = 0;
	scanf("%lf %d", &a, &b);
	printf("%lf", Power(a, b));
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值