计算a^b mod 1e9+7的Java代码存问题,求排查并修正
分析并修复a^b mod 1e9+7的Java代码问题
错误点分析
乘法操作时的整数溢出:
原代码中计算arr[index-1] * arr[index-1]时,两个int类型值直接相乘,结果会先以int存储。即使后续转换为long,溢出已经发生(比如当值接近1e9+7时,平方远超过int最大值2^31-1),导致结果变为负数,最终取模结果错误。数组填充逻辑冗余且易出错:
原代码通过数组存储每一步的平方结果,但循环条件count < n2会导致计算多余的项,且数组长度固定为33,逻辑不够简洁,增加了出错概率。未明确处理特殊边界情况:
当指数n2=0时,虽然后续计算结果为1(符合数学定义),但未明确处理0^0这种未定义的边界场景;逻辑上可以更清晰地覆盖各类特殊情况。
修正后的代码
import java.util.Scanner; public class Solution { protected static final int MOD = 1000000007; // 直接用常量,避免浮点转换误差 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); while (t-- > 0) { int a = sc.nextInt(); int b = sc.nextInt(); // 处理特殊边界:0^0 可根据题目需求调整,这里默认返回1 if (a == 0 && b == 0) { System.out.println(1); continue; } // 标准快速幂实现,用long避免溢出 long result = 1; long base = a % MOD; // 先对底数取模,减少计算量 int exponent = b; while (exponent > 0) { // 如果当前二进制位是1,将结果乘上当前base if ((exponent & 1) == 1) { result = (result * base) % MOD; } // base平方并取模 base = (base * base) % MOD; // 指数右移一位(等价于除以2) exponent = exponent >> 1; } System.out.println(result); } sc.close(); } }
代码说明
- 彻底避免溢出:所有乘法操作均使用
long类型进行计算,确保中间结果不会超出范围,计算完成后取模再存储,保证结果正确。 - 简洁高效:采用标准快速幂迭代写法,无需额外数组存储中间结果,时间复杂度为O(log b),处理大量输入更高效。
- 清晰的边界处理:明确处理
0^0的特殊情况,其他场景通过快速幂逻辑自然覆盖(如a=0,b>0时结果为0,b=0时结果为1)。
内容的提问来源于stack exchange,提问作者VIGNESH REDDY
相关产品推荐
相关产品推荐

