题目
分析
这个问题非常简单,我感觉是不用怎么分析的,为啥要把这么简单的题目也写到博客上呢?一定也有它的可取之处,多少人就曾经在这道题下全军覆没,面试官问这样的问题,显然不是想得到你30秒就能写下来的代码,在简单的问题面前一定要细心和严谨,一定要考虑到边界和特殊情况,让代码更加的健壮,更好一点就是提高你代码的运行效率。
拿这道题来说,我们分分钟就能写出下面的代码
下面我们开始挑毛病了啊,考虑特殊情况,如果是求base的0次方,那么会不会有问题?这个里边就是exponent
= 0,那么循环进不去,直接返回result =
1.0,所有数的0次方都为1(0的0次方可以规定为0,也可以规定为1),这点的话程序考虑到了;那么当exponent为负数时,还会不会有问题,卧槽,一下子漏洞就出来了,返回的还是1,显然程序把这种情况直接忽略掉了,我们知道求某个数的负数次方,其实就是求这个数的正数次方的倒数,显然作为分母,还得考虑分母是否为0的情况,总结下来就是考虑问题不全面,这样下来的话,这个问题就不简单了吧!
情况已经考虑完了,这个时候看看程序还能不能优化,也就是运行效率。
我们发现求数值的次方时,是用一个循环来进行乘法计算的,比如求一个数值的30次方,那么就得循环30次才能算出来,我们能不能在这个过程里优化一下,其实求30次方,不就相当于15次方和15次方相乘吗?也就是说计算到15次方的时候,直接求它自身的平方就行了,不用往后继续蛮算了,前一种方法就相当于傻逼一样,算完之后继续从头再来,而后一种就相当于人类的上下五千年一样,一代代后人都是站在前人的肩膀上,文明越来越进步。很明显30次方依赖15次方,那么15次方也会依赖7次方。。。一直往下走,最后依赖的是0次方或1次方,这是一个很清晰的递归过程。
考虑的细节,所求的次方可能是偶数,也有可能是奇数,因为上层依赖的是下层的平方,所以涉及到了对2的除法,偶数还好,奇数还会余1,可以总结出下面的公式:
当然我们中间还有判断次方是偶数还是奇数的步骤,我们平常是用百分号求余数来判断的,现在我们可以用与操作来代替,提高运行效率,将次方和1相与,次方的二进制最后一位之前的所有位和0相与都为0,如果最后一位是1的话,那么1和1相与,最后结果是1,否则是0,通过判断与操作结果是1还是0就可以判断出是奇数还是偶数。
那么我们就可以写出下面的递归代码
C代码
小知识:在判断两个小数是否相等时,不能直接用==比较,因为小数是有误差的,你可能感觉在逻辑上应该是相等的,但是小数在实际存储时会有一些误差,所以我们只能判断这两个小数的差是否在一个很小的范围内,在这个范围内就认为是相等的,否则就不等。
运行结果