/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//
/*
Q:
数值的整数次方:
实现一个函数double poew(double base, int exponent),
不得使用库函数,同时不需要考虑大叔问题
S:
1.充分考虑边界值,比如base=0时候,如果指数小于等0,在数学上没有意义,同时也会导致
计算机计算溢出;如果指数是负数的话,最后的结果应该是指数的绝对值次方的倒数。
2.把计算正数次方的方法进行优化。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
// 全局变量用于返回结果的检查,异常检查其是否非法输入
bool g_inValidInput = false;
/* 这里考虑到计算机内部比较两个数,只有两个数的差小于一个很小的数,才能保证 */
bool equal(double a, double b)
{
if((a - b) < 0.00000001 && (a - b) > -0.00000001)
{
return true;
}else{
return false;
}
}
/* 这里考虑的是计算正数次幂 */
double absPower(double base, unsigned int absExponent)
{
double result = 1.0;
for(int i = 0; i < absExponent; ++i)
result *= base;
return result;
}
/* 真正需要计算函数 */
double powerOne(double base, int exponent)
{
if(equal(base, 0.0) && exponent <= 0)
{
g_inValidInput = true;
return 1;
}
unsigned int absExponent = (unsigned int)exponent;
if(exponent < 0)
absExponent = (unsigned int)(-exponent);
double result = absPower(base, absExponent);
if(exponent < 0)
return (1.0 / result);
return result;
}
double absPowerFast(double base, unsigned int absExponent)
{
if(absExponent == 0)
return 1;
if(absExponent == 1)
return base;
double result = absPowerFast(base, absExponent >> 1);
result *= result;
if(absExponent & 0x01)
return result*base;
return result;
}
double powerTwo(double base, int exponent)
{
if(equal(base, 0.0) && exponent <= 0)
{
g_inValidInput = true;
return 1;
}
unsigned int absExponent = (unsigned int)exponent;
if(exponent < 0)
absExponent = (unsigned int)(-exponent);
double result = absPowerFast(base, absExponent);
if(exponent < 0)
return (1.0 / result);
return result;
}
void test(double output, double expect)
{
if(equal(output, expect))
{
std::cout << "Test pass. output=" << output << ", expect=" << expect << std::endl;
}else{
std::cout << "Test fail. output=" << output << ", expect=" << expect << std::endl;
}
}
void test_powerOne()
{
test(powerOne(1, 0), 1);
test(powerOne(1, 2), 1);
test(powerOne(4, 4), 256);
test(powerOne(1, -1), 1);
test(powerOne(2, -1), 0.5);
test(powerOne(-2, -2), 0.25);
test(powerOne(-2, -1), -0.5);
test(powerOne(0, -1), 1);
test(powerOne(0, 0), 1);
}
void test_powerTwo()
{
test(powerTwo(1, 0), 1);
test(powerTwo(1, 2), 1);
test(powerTwo(4, 4), 256);
test(powerTwo(1, -1), 1);
test(powerTwo(2, -1), 0.5);
test(powerTwo(-2, -2), 0.25);
test(powerTwo(-2, -1), -0.5);
test(powerTwo(0, -1), 1);
test(powerTwo(0, 0), 1);
}
int main(int argc, char**argv)
{
test_powerOne();
test_powerTwo();
return 0;
}
剑指offer-输出数值的整数次幂结果
最新推荐文章于 2021-07-14 21:10:18 发布