博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
16 数值的整数次方 (第3章 高质量的代码-代码的完整性)
阅读量:5173 次
发布时间:2019-06-13

本文共 3240 字,大约阅读时间需要 10 分钟。

题目描述:

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

不只要通过测试,要更着重代码的优化

 

测试用例:

base与exponent分别取正数、0、负数  共3*3九种情况

 

解题思路:

1)为base与exponent区分正数、0、负数  全面但是不够高效率的解法

class Solution {public:  bool g_InvalidInput = false;    double Power(double base, int exponent) {        if(base==0 && exponent<=0){  //相等这是否有问题??? 修改为 abs(base-0.0)<10e-10            //0^0没有意义 而1/0 0不能为分母 g_InvalidInput = true; //用于标记是由于出错,返回0(此时该值为true),若是由计算结果返回0,该值为false。                         return 0.0;        }        double result = 1.0;        //确定是正值,用无符号比较好        unsigned int absExponent = (unsigned int)(exponent); //int到unsigned int要显示转换        if(exponent<0)            absExponent = (unsigned int)(-exponent);        /*if(exponent<0)            int absExponent = -exponent;  //for处会显示没有定义absExponent变量        else             int absExponent = exponent;*/               for (int i=0;i

注:[1]  对于double类型而言,由于精度的原因,不能用等号判断两个小数是否相等。因为double类型的表示往往是不精确的(近似表示),有精度范围的那种。如果是运算结果,即使都是0.0,也不保证相等!一般用一个容差e(很小的值)。

       [2] 上述代码采用全局变量 g_InvalidInput 来标识是否出错(函数返回0时,是由于计算结果为零,还是错误的输入)。但是在使用函数返回值时,如 double result = Power(2,3); 调用时,常常容易忘记检查 g_InvalidInput 以判断是否出错

 

2全面又高效的算法 时间复杂度O(logn)

当exponent=32时,要计算31次乘法。但是如果知道16的平方,再平方即可得到最终解。这样经过5次计算就可以得到最终解。

//实现1:递归调用 class Solution {public:    bool g_InvalidInput = false;    double Power(double base, int exponent) {        if(abs(base-0.0)<10e-10 && exponent<=0){              //0^0没有意义 而1/0 0不能为分母            g_InvalidInput = true; //用于标记是由于出错,返回0(此时该值为true),若是由计算结果返回0,该值为false。                        return 0.0;        }        double result = 1.0;        //确定是正值,用无符号比较好        unsigned int absExponent = (unsigned int)(exponent); //int到unsigned int要显示转换        if(exponent<0)            absExponent = (unsigned int)(-exponent);        /*if(exponent<0)            int absExponent = -exponent;  //for处会显示没有定义absExponent变量        else             int absExponent = exponent;*/               for (int i=0;i
>1); //右移代替除以2 result*=result; if(exponent&0x1==1) //位与操作,最后一位是1,则一定是奇数。最后一位是0,则一定是偶数。 exponent%2==1 也可以判断,但是效率很低 result*=base; return result; }};  

 代码中的两处细节:判断base是否为0,以及用位运算代替乘除法以及取余运算。

位运算的效率比乘除法及求余运算的效率要高很多!!  

//实现2:循环实现class Solution {public:    bool g_InvalidInput = false;    double Power(double base, int exponent) {        double result = 1,currBase = base;        int absExponent;        if(exponent>0){            absExponent = exponent;        }else if(exponent<0){            if(base==0.0){                g_InvalidInput = true;                return 0.0;                //throw new RuntimeException("分母不能为0");             }            absExponent = -exponent;        }else{// n==0            return 1;// 任何数的0次幂(包括0的0次方)。        }   //循环实现        while(absExponent!=0){            if((absExponent&1)==1) //奇数                result*=currBase;            currBase*=currBase;// 翻倍,记录的是基数            absExponent>>=1;// 右移一位,除以2        }                return exponent>=0?result:(1/result);        }};  

指数计算:

  • 当n为偶数,a^n =(a^n/2)*(a^n/2)
  • 当n为奇数,a^n = a^[(n-1)/2] * a^[(n-1)/2] * a
  • 2^11 = 2^1 * 2^2 * 2^8     //其中11的二进制表示位 :1011 将其拆分为:100000100001
  • 2^1011 = 2^0001 * 2^0010  * 2^1000

 

转载于:https://www.cnblogs.com/GuoXinxin/p/10419228.html

你可能感兴趣的文章
把二元查找树转变成排序的双向链表
查看>>
input与select 设置相同宽高,在浏览器上却显示不一致,不整齐
查看>>
NUGET常用命令
查看>>
CentOs下Apache+Python+Django+mod_wsgi环境搭建
查看>>
java基础知识总结(3)
查看>>
spark配置
查看>>
数据仓库 - 3.数据仓库基本概念
查看>>
自定义树莓派的显示分辨率
查看>>
sql full left right inner cross 基础
查看>>
SpringBoot + Mybaties的逆向工程有数据库生成domain的过程
查看>>
Android控件TextView之跑马灯功能问题记录
查看>>
国外漂亮质感网页设计作品欣赏 转
查看>>
SVN学习总结
查看>>
cognos安装 win7+Sqlserver08SP1
查看>>
Java的21个技术点和知识点归纳
查看>>
安卓中Paint类和Canvas类的方法汇总
查看>>
提供openssl -aes-256-cbc兼容加密/解密的简单python函数
查看>>
数据结构-表
查看>>
【转载】下一代Web应用模型:Progressive Web App
查看>>
gridControl 部分属性
查看>>