数值的整数次方


面试题11:数值的整数次方

一.题目描述

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

二.分析问题

1.解题思路

解法1

这道题因为不用考虑大数的问题,所以比较简单,但是我们不能因此掉以轻心,要将所有可能出现的情况考虑清楚。

  • 如果指数为负数的时候,我们先对指数求绝对值,然后算出次方的结果之后再取倒数。
  • 当底数是零且指数是负数的时候,如果不做特殊处理,就会出现对0求导数从而导致程序运行错误。
  • 如果底数和指数其中任意一个为0,就返回1。

细节:

但我们在判断底数是不是等于0的时候,不能直接写 base == 0,这是因为在计算机内表示小数时(包括float和double型小数)都有误差。判断两个小数是否相等,只能判断他们之差的绝对值是不是在一个很小的范围内。如果两个数相差很小,就可以认为它们相等。

解法2

如果我们输入的指数exponent为32,在解法1中我们要循环31次乘法。但我们知道32是16的平方,而16次方是8的平方。以此类推,我们只需要知道它的2次方,接着再平方......我们只需要做5次乘法循环。

因此我们可以推导出以下公式:

三.代码

解法1

#include<stdio.h>
#include<stdlib.h>

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

double PowWithUnsigned(double base, unsigned int exponent)
{
	double result = 1.0;

	for (unsigned int i = 1; i <= exponent; ++i)
	{
		result *= base;
	}
	return result;
}

double Power(double base, int exponent)
{
	if (equal(base, 0.0))//判断base是不是0
	{
		return 0.0;
	}
	if (exponent == 1)
	{
		return base;
	}
	if (exponent == 0)
	{
		return 1;
	}

	unsigned int abs_exponent = (unsigned int)exponent;
	if (exponent < 0)
	{
		abs_exponent = (unsigned int)(-exponent);//如果指数小于0,则取它的绝对值
	}

	double result = PowWithUnsigned(base, abs_exponent);

	if (exponent < 0)/*如果指数小于0,则取它的倒数*/
	{
		result = 1.0 / result;
	}
	return result;
}



int main()
{
	double a = 2;
	int b = 6;
	printf("%lf\n", Power(a, b));
	return 0;
}

运行结果:

解法2

#include<stdlib.h>
#include<stdio.h>

double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
	if (exponent == 0)
	{
		return 1;
	}
	if (exponent == 1)
	{
		return base;
	}

	double result = PowerWithUnsignedExponent(base, exponent >> 1);//右移一位相当于除以2
	result *= result;
	if ((exponent & 1) == 1)//判断是否为奇数
	{
		result *= base;
	}
	return result;
}


int main()
{
	double a = 2;
	int b = 6;
	printf("%lf\n", PowerWithUnsignedExponent(-1,3));
	return 0;
}

运行结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值