算法之数值的整数次方
要求:实现特定库函数pow.
解决思路:首先常规的解法大家肯定都会,这里主要是一种高效而且很全面的方法。我们要考虑如果输入的指数小于1,也就是零和负数的时候,怎么办呢?
这样办,可以先对指数求绝对值,然后算出次方的结果后,再取倒数。那么,问题来了,底数是0的时候,0没有倒数啊,假如你对0求了倒数,那岂不是让程序出错。
为了不使程序出错,这里做一下特殊处理。当底数为0而且指数是负数的时候,我们设立一个布尔型的全局变量,出错时,全局变量为true,返回值为0;
那么不出错的时候,全局变量也就是false了。
代码中用到的公式说明:如果输入的指数是exponent为32,则在函数powerwithunsignedexponent的循环中需要做31次乘法。但是我们其实可以不用这么多次的。
如何做?平方的思想!如果你要求2的8次方,那么在算到2的4次方的时候,把2的4次方平方一下,就得到2的8次方。
同理,若求2的16次方,直接把2的8次方平方一下,那么,是不是就少了很多次的乘法步骤呢。
必然,这就是平方的强大之处。所以有如下的公式,我们直接用就好了。
求a的n次方:
核心代码:
'''
bool g_invalidinput=false; double power(double base,int exponent) { g_invalidinput=false;//全局变量 if((equal(base,0,0)&(exponnent<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; double powerwithunsignedexponent(int base,unsigned int exponent) { if(exponent==0) return 1; if(exponent==1) return base; double result = powerwithunsignedexponent(base, exponent >> 1);//递归 //利用右移来代替除法,提高效率 result*=result;//利用公式 if(exponent&0x1==1)//判断奇偶性,如果为奇,那么还要乘以base. return result*base; return result;//若为偶,平方后直接输出即可
整体代码(包含测试):
'''
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; double powerwithunsignedexponent(double base, unsigned int exponent); bool g_invalidinput = false;//有效位设为false。 bool equal(int num1, int num2)//判断两数是否相同 { if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001)) return true; else return false; } double power(double base, int exponent)//考虑到特殊情况 { g_invalidinput = false; if (equal(base,0.0) && exponent < 0)//底数为0,指数为负数的情况 { g_invalidinput = true;//出错时为true return 0.0;//返回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; } double powerwithunsignedexponent(double base, unsigned int exponent) {//这是求幂的运算 if (exponent == 0) return 1; if (exponent == 1) return base; double result = powerwithunsignedexponent(base, exponent >> 1); //利用右移来代替除法,提高效率 result *= result;//利用公式 if (exponent & 0x1 == 1)//判断奇偶性,如果为奇,那么还要乘以base. result *= base; return result;//若为偶,平方后直接输出即可 } void test(const char* testname, double base, int exponent, double expectedresult, bool expectedflag) { double result = power(base, exponent); if (equal(result, expectedresult) && g_invalidinput == expectedflag) std::cout << testname << " passed" << std::endl; else std::cout << testname << "failed" << std::endl; } int main(int argc, char* argv[]) { test("test1", 3, 2, 9,false ); test("test2", -2, 3, -8, false); test("test3", 0, -1, 0, true);//底数为0,指数为负数的时候,特殊处理 }
学习让我快乐,工作让我快乐。学习和工作都是为了更好的生活!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)