学习记录:Java的快速幂函数

函数介绍:接受两个整数参数 a 和 b,并返回 (a^b) 的结果

public static int quickpow(int a, int b) {  
    int ans = 1;  
    while (b > 0) {  
        if ((b & 1) == 1) {  
            ans *= a;  
        }  
        a *= a;  
        b >>= 1;  
    }  
    return ans;  
}

变量初始化

int ans = 1 ;

这里 ans 初始化为1,因为在幂运算中,任何数的0次方都是1。

判断指数的奇偶性


	if ((b & 1) == 1) { 

	ans *= a; 

	}

在快速幂算法中,判断指数的奇偶性是关键步骤,因为算法依赖于二进制表示来减少乘法次数。如果指数 b 是奇数,那么在计算 a^b 时,当前的底数 a 必须被乘入结果 ans 中。如果 b 是偶数,则当前的 a 不需要直接乘入 ans,因为 a 的平方将在后续的迭代中计算。

在二进制表示中,一个数的最低位(即最右边的位)决定了这个数是奇数还是偶数。如果该位是1,则这个数是奇数;如果该位是0,则这个数是偶数。位运算 b & 1 就是用来检查 b 的最低位是否为1的。

因此,在快速幂算法中,判断奇偶性的目的是确定在当前迭代中是否需要将 a 乘入 ans。这是算法正确性的关键部分,因为它确保了只有在需要时才进行乘法运算,从而减少了总的乘法次数。

举例来说,假设我们要计算 a^13。在二进制中,13 表示为 1101。快速幂算法会按如下方式计算:

  1. b = 13ans = 1a 保持不变
  2. b 是奇数 (13 & 1 = 1),所以 ans *= a(此时 ans = a
  3. a 自乘:a *= a(此时 a = a^2
  4. b 右移一位:b >>= 1(此时 b = 6
  5. b 是偶数 (6 & 1 = 0),所以 ans 不变
  6. a 自乘:a *= a(此时 a = a^4
  7. b 右移一位:b >>= 1(此时 b = 3
  8. b 是奇数 (3 & 1 = 1),所以 ans *= a(此时 ans = a^5
  9. a 自乘:a *= a(此时 a = a^8
  10. b 右移一位:b >>= 1(此时 b = 1
  11. b 是奇数 (1 & 1 = 1),所以 ans *= a(此时 ans = a^13
  12. 算法结束,返回 ans

通过判断奇偶性,我们可以确保只在需要时才进行乘法运算,从而优化算法的性能。如果忽略了这一步,那么每次迭代都会进行乘法运算,这将导致算法退化为简单的幂运算,失去了快速幂算法的优势。

使用位运算来判断 b 的最低位是否为1(即判断 b 是否为奇数)。如果 b 是奇数,那么我们需要将当前的 a 值乘到 ans 上。

平方底数

a *= a;

无论 b 是奇数还是偶数,我们都需要将 a 自乘,以便在下一次迭代中使用它的平方值。

指数右移

b >>= 1;

将 b 右移一位,相当于将 b 除以2。这是因为我们在每一次循环中已经处理了 b 的最低位。

TIPS:这个版本的函数没有考虑整数溢出的问题。在实际应用中,如果 a 和 b 非常大,可能会导致 ans 的值溢出 int 类型的范围。如果需要处理大整数幂运算,可能需要使用 BigInteger 类或其他方法来避免溢出问题。

 

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值