求整数幂的c语言代码,剑指offer面试题之求数值的整数次方

题目

a4c26d1e5885305701be709a3d33442f.png

分析

这个问题非常简单,我感觉是不用怎么分析的,为啥要把这么简单的题目也写到博客上呢?一定也有它的可取之处,多少人就曾经在这道题下全军覆没,面试官问这样的问题,显然不是想得到你30秒就能写下来的代码,在简单的问题面前一定要细心和严谨,一定要考虑到边界和特殊情况,让代码更加的健壮,更好一点就是提高你代码的运行效率。

拿这道题来说,我们分分钟就能写出下面的代码

a4c26d1e5885305701be709a3d33442f.png

下面我们开始挑毛病了啊,考虑特殊情况,如果是求base的0次方,那么会不会有问题?这个里边​就是exponent

= 0,那么循环进不去,直接返回result =

1.0,所有数的0次方都为1(0的0次方可以规定为0,也可以规定为1),这点的话程序考虑到了;那么当exponent为负数时,还会不会有问题,卧槽,一下子漏洞就出来了,返回的还是1,显然程序把这种情况直接忽略掉了,我们知道求某个数的负数次方,其实就是求这个数的正数次方的倒数,显然作为分母,还得考虑分母是否为0的情况,总结下来就是考虑问题不全面,这样下来的话,这个问题就不简单了吧!

a4c26d1e5885305701be709a3d33442f.png

情况已经考虑完了,这个时候看看程序还能不能优化,也就是运行效率。

我们发现求数值的次方时,是用一个循环来进行乘法计算的​,比如求一个数值的30次方,那么就得循环30次才能算出来,我们能不能在这个过程里优化一下,其实求30次方,不就相当于15次方和15次方相乘吗?也就是说计算到15次方的时候,直接求它自身的平方就行了,不用往后继续蛮算了,前一种方法就相当于傻逼一样,算完之后继续从头再来,而后一种就相当于人类的上下五千年一样,一代代后人都是站在前人的肩膀上,文明越来越进步。很明显30次方依赖15次方,那么15次方也会依赖7次方。。。一直往下走,最后依赖的是0次方或1次方,这是一个很清晰的递归过程。

考虑的细节,所求的次方可能是偶数,也有可能是奇数​,因为上层依赖的是下层的平方,所以涉及到了对2的除法,偶数还好,奇数还会余1,可以总结出下面的公式:

a4c26d1e5885305701be709a3d33442f.png

当然我们中间还有判断次方是偶数还是奇数的步骤,我们平常是用百分号求余数来判断的,现在我们可以用与操作来代替,提高运行效率,将次方和1相与,次方的二进制最后一位之前的所有位和0相与都为0,如果最后一位是1的话,那么1和1相与,最后结果是1,否则是0,通过判断与操作结果是1还是0就可以判断出是奇数还是偶数。

那么我们就可以写出下面的递归代码

a4c26d1e5885305701be709a3d33442f.png

C代码

小知识:在判断两个小数是否相等时,不能直接用==比较,因为小数是有误差的,你可能感觉在逻辑上应该是相等的,但是小数在实际存储时会有一些误差,所以我们只能判断这两个小数的差是否在一个很小的范围内,在这个范围内就认为是相等的,否则就不等。

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

运行结果

a4c26d1e5885305701be709a3d33442f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值