数值的整数次方(不考虑结果的大数问题)优秀的代码就是要注意细微的细节

数值的整数次方(优秀的代码就是要注意很多的细节)

通常越是看似简单的题目(因为没有大数问题),其实真正写代码的时候就会忘记很多的细节

比如此题大多数童鞋估计看到后就会立刻写出如下代码

double powerWithUnsignedExponent(double base, int exponent){
	double result = 1.0;
	for(int i = 0; i <= exponent; ++i){
		result *= base;
	}
	return result;
}

可是如果你写出上面的代码立刻就交给了面试官,那也意味着你与offer已经无缘了

当然前提你需要写出逻辑正确的代码,然后才是优化性能

需要注意的几个点:1如果幂exponent为负数呢  2、底数如果是 0 && 幂为负数呢  3如果输入非法怎么告知调用函数者 4、能不能更高效

其中有个容易遗忘的知识点   double a;    不能用 a == 0 来判断a是否为0   因为对于double类型来说 0 不是绝对精确的结果;  所以应该用类似 abs(a - 0.0 ) < 0.000001 来判断

第一点:如果幂exponent为负数  首先计算出幂为整数的值 然后取倒数即可;   

第二、三点:对于输入非法的情况,我们有三种解决办法 a、异常(高级语言推荐)优点:可以为不同的出错原因定义不同异常类型 逻辑清晰  缺点:抛出异常对性能有些许负面影响    b、设置一个全局变量标志来指示输入非法与否;优点:能方便的使用计算结果,缺点:调用者容易忘记判断标志符; c、用返回值,优点:和系统API一致  缺点:不能方便的使用计算结果

第四点:把exponent 拆开计算  分奇数与偶数两种情况  (基本的数学原理)

public static double power(double base, int exponent) throws Exception{
		
		//如果底为0  幂为负数  则为非法输入
		if( Math.abs(base-0.0) < 0.0000001 && exponent < 0 ){
			
			throw new Exception("您输入的底数与幂有错误,请检查");
		}
		
		if( 1.0 == base ){
			return 1.0;
		}
		
		int absExponent = Math.abs(exponent);   //absExponent 为exponent取正值
		
		double result = powerWithUnsignedExponent(base,absExponent);  //调用幂为正的合法计算结果
		
		if(exponent < 0){      //如果幂为负值,则把幂为正的计算结果取倒数即可
			
			result = 1.0/result;
		}
		
		return result;       
	}
	
	//计算输入合法且 幂为正的结果
	private static double powerWithUnsignedExponent2(double base, int exponent){
		double result = 1.0;
		for(int i = 0; i <= exponent; ++i){
			result *= base;
		}
		return result;
	}

 

上述代码不一定会让面试官十分满意,因为还可以更高效,函数double powerWithUnsignedExponent(double base, int exponent) 可以改为如下高效的算法

public static double powerWithUnsignedExponent(double base, int exponent){
		
		if( 0 == exponent ){
			return 1.0;
		}
		if( 1 == exponent){
			return base;
		}
		
		double result = powerWithUnsignedExponent(base, exponent >> 1);
		result *= result;
		if( 1 == (exponent & 0x1))
			result *= base;
		return result;
	}

上述代码中 exponent >> 1 代替了除以2   位与运算代替了求余(%)运算  因为位运算要比乘除法运算要高效很多,既然优化性能就要优化到极致

但是上述代码虽然得到了性能优化,但是有一定的风险,因为用到了递归;就要考虑 栈 的问题,如果递归过深   有 栈溢出的风险,这个就要和面试官沟通了



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值