剑指Offer:面试题11 数值的整数次方

/*
数值的整数次方:
实现函数double Power(double base,in exponent),求base得exponent(指数)次方,不得使用库函数,同时不
需要考虑大数问题。


输入:
输入可能包含多个测试样例。
对于每个输入文件,第一行输入一个整数T,表示测试案例的数目,接下来的T行每行输入一个浮点数base和一个整数exponent,两个数中间用一个空格隔开。
输出:
对应每个测试案例,
输出一个浮点数代表答案,保留两位小数即可。
样例输入:
5
1.0 10
0.0 -5
1.0 0
1.2 5
2.0 -1
样例输出:
1.00e+00f(没)
INF (没)
1.00e+00f(通过)
2.49e+00f(没)
5.00e-01f(没)


思路:
决定采用累乘相加的方法
*/


/*
关键:
1 记住如果底数为0,指数小于0,则输出0,并置全局错误标记值为错误
g_invalidParam = false;//对全局变量初始化
if(equal(dBase,0.0) && iExp < 0)//对底数为0,指数小于0的情况进行判断。注意判断两个浮点数是否相等,利用两数之差的绝对值是否在一个很小的范围之内
{
g_invalidParam = true;
return 0.0;
}
2 如果底数不为0,指数小于0,用1/x^n来做
return 1.0/dRes;//注意这里用1.0不是用1
3 一看到求次方问题,就要想到用递归公式来求解
a^n = {a^(n/2) * a^(n/2)
      {a^((n-1)/2)*a^((n-1)/2)*a
if(iExp == 0)//x^0 = 1,特殊地方
{
return 1.0;
}
if(iExp == 1)//递归出口
{
return base;
}
double dRes = powerUnsignedExp(base,iExp >> 1);//用右移代替除以2
dRes *= dRes;
if((iExp & 0x1) == 1)//用与1运算判断是否指数为奇数
{
dRes *= base;


*/


#include <stdio.h>


bool g_invalidParam = false;//设置全局错误标记


double powerUnsignedExp(double base,unsigned int iExp)
{
if(iExp == 0)//x^0 = 1,特殊地方
{
return 1.0;
}
if(iExp == 1)//递归出口
{
return base;
}
double dRes = powerUnsignedExp(base,iExp >> 1);//用右移代替除以2
dRes *= dRes;
if((iExp & 0x1) == 1)//用与1运算判断是否指数为奇数
{
dRes *= base;
}
return dRes;
}


bool equal(double num1 ,double num2)
{
if(num1 - num2 > -0.0000001 && num1 - num2 < 0.0000001)
{
return true;
}
else
{
return false;
}
}


double power(double dBase,int iExp)//为什么这里2.0 - 0.0会比0.00000001小啊
{
//if((dBase - 0.0 < 10e-7 || 0.0 - dBase < 10e-7) && iExp <0)//对底数为0,指数小于0的情况进行判断。注意判断两个浮点数是否相等,利用两数之差的绝对值是否在一个很小的范围之内
//if((dBase - 0.0 < 0.0000001 || 0.0 - dBase < 0.0000001) && iExp <0)
g_invalidParam = false;//对全局变量初始化
if(equal(dBase,0.0) && iExp < 0)//对底数为0,指数小于0的情况进行判断。注意判断两个浮点数是否相等,利用两数之差的绝对值是否在一个很小的范围之内
{
g_invalidParam = true;
return 0.0;
}
unsigned int iAbsExp = (unsigned int)(iExp > -1*iExp ? iExp : -1 * iExp);
double dRes = powerUnsignedExp(dBase,iAbsExp);
if(iExp > 0)
{
return dRes;
}
else//如果iExp为负,我们利用公式x^(-n) = 1/x^n
{
return 1.0/dRes;//注意这里用1.0不是用1
}
}


void process()
{
int n;
while(EOF != scanf("%d",&n))
{
double dBase;
int iExp;
while(n-- >= 0)
{
scanf("%f %d",&dBase,&iExp);
printf("%.2f\n",power(dBase,iExp));//注意,科学计数法用%e
}
}
}


int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值