快速幂解决a的n次方

1.技巧

比如 5的13次方,我们可以将13转为2进制1101——>也就是8,4,1(2的三次,2的二次,2的0次),所以为5^8 * 5^4* 5^1,时间复杂度变为0(logn)

2.error

快速幂是一种用来快速计算一个数的整数次方的算法,在实现过程中,经常会涉及到幂运算,即将一个数不断地自乘。如果使用 int 类型存储运算结果,当幂次较大时中间结果容易超出 int 类型取值范围,导致溢出。

int 类型在内存中通常占用 4 个字节,它的最大值为 2^31-1,最小值为 -2^31(32767~-32768)。当一个 int 型变量超出这个范围时,其值会发生“环绕”,即从最大值跳转到最小值,或者从最小值跳转到最大值。这种情况下,程序的行为就会出现异常,无法得到正确的结果。

为了避免这种问题,我们可以使用更高精度的数据类型或者采用取模运算的技巧来防止结果溢出。例如,在进行幂运算时,我们可以在每一步计算后都对结果取模,以保证结果不会超出 int 类型的范围。这样做既能提高计算效率,又能保证结果的正确性。

2.1解决方案1:更改数据类型

因为int为四字节,32bit,所以范围为-32768~32767,当幂过大,时会超出范围,导致环绕现象出现,即最大值跳至最小值,或是最小值跳至最大值
这里注意long和double的区别
https://blog.csdn.net/weixin_57128596/article/details/135716314?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135716314%22%2C%22source%22%3A%22weixin_57128596%22%7D

int getN(double a,int n){
  double res=1.0;
  int absN=Math.abs(n); //处理n<0的情况
  while(absN>0){ //n以二进制形式逐级递减
     if((absN&1)==1){
      res=res*a; //当最后一位为1时,即n为奇数,则更新res 
     } 
     //每次更新底数,并更新n
     a*=a;
     absN>>=1; //右移一位,变小/2
  }
  return n>0?res:1/res;
}

你可能感兴趣的:(java,算法,数据结构)