LeetCode Pow(x,n)问题:n=-2147483648时结果异常的技术咨询
解决LeetCode Pow(x,n)问题的两个疑问
我在做LeetCode的Pow(x,n)问题时,遇到最后一个测试用例失败:当输入x=2.00000、n=-2147483648时,我的代码返回1,而预期结果是0。有两个疑问需要解决:
疑问1:为什么该测试用例的正确结果是0?
当x=2.0,n=-2147483648时,实际要计算的是1/(2^2147483648)。这个数值极小,远小于Java中double类型能表示的最小非零正数值(约为2.2e-308),所以会触发下溢,被自动转换为0.0,这就是预期结果为0的原因。
疑问2:为什么调用Math.abs(n)仍返回-2147483648?
Java中int类型的取值范围是-2^31(即-2147483648)到2^31-1(即2147483647)。当对-2147483648调用Math.abs()时,理论上的绝对值是2147483648,但这个数超出了int的最大值,会发生整数溢出。根据补码的运算规则,溢出后的结果又回到了-2147483648,所以Math.abs(-2147483648)的返回值还是负数。
代码问题分析与修复
原代码中,当n为-2147483648时,Math.abs(n)返回的还是负数,导致进入n<0分支后,调用getDFS(x, 负数),而getDFS中处理负数n的逻辑存在漏洞(比如n/2 >=1不成立,saveData保持1,最后返回1*1=1,所以1/1=1,得到错误结果)。
修复方案是将n转换为long类型处理,避免溢出:
class Solution { public double myPow(double x, int n) { // 转换为long类型处理绝对值,避免int溢出 long N = n; if (N == 0) return 1; if (N < 0) { x = 1 / x; N = -N; } return getDFS(x, N); } private double getDFS(double x, long n) { if (n == 1) { return x; } double saveData = getDFS(x, n / 2); if (n % 2 == 1) { return saveData * saveData * x; } return saveData * saveData; } }
另外,原getDFS中的if (n / 2 >= 1)判断多余,递归会自然处理到n=1的终止条件,简化后代码更简洁且逻辑正确。
内容的提问来源于stack exchange,提问作者mattsmith5
相关产品推荐
相关产品推荐

