数值的整数次方

时间:2022-03-31 20:38:04

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

题目链接:http://ac.jobdu.com/problem.php?pid=1514

这道题目有以下几点需要注意:

  1. 0的0次方是无意义的,非法输入
  2. 0的负数次方相当于0作为除数,也是无意义的,非法输入
  3. base如果非0,如果指数exponent小于0,可以先求base的|exponent|次方,然后再求倒数
  4. 判断double类型的base是否等于0不能使用==号。因为计算机表述小树(包括float和double型小数)都有误差,不能直接使用等号(==)判断两个小数是否相等。如果两个数的差的绝对值很小,那么可以认为两个double类型的数相等。
根据以上四个注意点,我们可以写出求指数的程序,代码:
#include<iostream>
#include<cstdio>
#include<iomanip>
using namespace std;

bool g_Invalid = false;
//由于计算机表示小数(float,double)都有误差,不能直接用等号(==)来判断两个数是否相等
//所以若两个数的差的绝对值很小很小,比如小于0.0000001,就可以认为他们是相等的
bool equal(double num1, double num2)
{
	if ((num1 - num2) > -0.000001 && (num1 - num2) < 0.000001)
		return true;
	else 
		return false;
}
//传进来的exp是>=0的
double PowerExp(double base, unsigned int exp)
{
	if (exp == 0)
		return 1;
	if (exp == 1)
		return base;

	double res = PowerExp(base,exp>>1);
	res *= res;

	if (exp &0x1 == 1)
		res *= base;

	return res;
}

double Power(double base, double exp)
{
	g_Invalid = false;
	
	//0的0次方及0的负数次方都是非法输入
	if (equal(base,0.0) && exp <= 0)
	{
		g_Invalid = true;
		return 0.0;
	}
	//取指数的绝对值
	unsigned int absExp;
	if (exp < 0)
		absExp = (unsigned int)(-exp);
	else 
		absExp = (unsigned int)(exp);
	
	double res = PowerExp(base,absExp);
	
	//指数小于0,则取倒数
	if (exp < 0)
		res = 1.0/res;

	return res;

}
int main()
{
	int t, exp;
	double base, res;
	while (scanf("%d",&t) == 1)
	{
		for (int i = 0; i < t; i++)
		{
			scanf("%lf %d",&base,&exp);
			res = Power(base,exp);
			//如果非法输入,输出INF
			if (g_Invalid )
			{
				printf("INF\n");
				continue;
			}
			//注意输出格式,科学计数法的表示
			else 
			    printf("%.2ef\n",res);
		}
	}
	return 0;
}
此题必须仔细才能写好。