数值的整数次方

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

  需要注意的要点如下:

  • 计算机表示小数(包括float和double型小数)都有误差不能直接用==判断是否相等。如果两个小数的差的绝对值很小,就可以认为它们相等。
  • 如果幂exponent为负数的话,相当于对求得的结果取倒数,但,底数base为0的时候,倒数是不合法的。
  • double Power(double base, int exponent);输入的参数是有符号数为了使问题更简洁,建议写一个专门处理无符号数的函数,然后让上述函数调用它。
  • 处理后,使得base不为0幂exponent是无符号数。求结果思路就比较清晰了。是如果采用循环,把底数base连乘exponent次,效率过低,在这里,建议使用位运算(右移一位表示除2,只有无符号数不会出现差错)。具体实现详见代码。

  本道题目需要注意的地方大概就是这些了。下面是代码:

#include<stdio.h>
bool g_InvalidInput = false;
float const deviation = 0.0000001;

/*
**判断两个浮点数是否相等。
*/
bool
equal(double num1, double num2)
{
	if ((num1 - num2 > -deviation) && (num1 - num2) < deviation)
	{
		return true;
	}
	else
	{
		return false;
	}
}


/*
**处理无符号整型幂,底数base不为0的输出。
*/
double
PowerWithUnsignedExponent(double const base, unsigned int const exponent)
{
	/*
	**参数有效性检查。
	**任何非零数的零次幂都为1,
	**任何非零数的一次幂都是本身。
	*/
	if (0 == exponent)
	{
		return 1;
	}
	if (1 == exponent)
	{
		return base;
	}

	/*
	**无符号数右移一位相当于是除以2。
	**比如7右移一位结果是3,位运算连判断奇偶数都省略了。
	**在这里进行递归调用。
	*/
	double result = PowerWithUnsignedExponent(base, exponent >> 1);
	result *= result;

	/*
	**是奇数的话,少乘了一次,在此补充。
	*/
	if (1 == exponent & 0x1)
	{
		result *= base;
	}

	return result;
}


/*
**处理一般数值的整数次方。
*/
double
Power(double base, int exponent)
{
	g_InvalidInput = false;

	if (equal(base, 0.0) && exponent < 0)
	{
		g_InvalidInput = true;
		return 0.0;
	}
	
	/*
	**取绝对值。
	*/
	unsigned int absExponent = (unsigned int)(exponent);
	if (exponent < 0)
	{
		absExponent = (unsigned int)(-exponent);
	}

	double result = PowerWithUnsignedExponent(base, absExponent);
	if (exponent < 0)
	{
		result = 1.0 / result;
	}

	return result;
}

int
main()
{
	double result = Power(-3, 2);
	printf("%f\n", result);
	return 0;
}
本程序在VS2017下运行通过
阅读更多
版权声明:本文为博主原创文章,若要转载注明出处即可,欢迎分享! https://blog.csdn.net/qq_41822235/article/details/80345946
文章标签: 位运算 无符号数
个人分类: C/C++ 剑指Offer
上一篇利用位运算的特点做加法
下一篇插入排序------直接插入排序(1)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭