我在leetcode中编写了一个简单问题的代码。它要求实现pow(x,n);它告诉我“运行时错误”,上次执行输入:1.00000,-2147483648。我换成了另一种方法,有效。但我只是想知道我在下面的代码中做错了什么。非常感谢!!
class Solution {
public:
double pow(double x, int n) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(n==0 && x==0) return 1.0;
if(x==0) return 0;
if(n==0) return 1.0;
if(n<0) return 1/pow(x,-n);
if(n==1) return x;
double y=pow(x,n/2);
if(n%2==1) return y*y*x;
else return y*y;
}
};
答案 0 :(得分:6)
假设int
的长度为32位,-2147483648
是一个唯一值,而不是0,其中的否定等于它自己。这一行:
if(n<0) return 1/pow(x,-n);
使用相同的参数调用自身,并且直到堆栈溢出为止。
更详细地说,-2147483648的二进制表示是:
10000000000000000000000000000000
那是1
后跟31 0
s。根据{{3}}取消否定是一个两步过程。 1)将所有0
更改为1
,反之亦然:
01111111111111111111111111111111
然后2)加1:
10000000000000000000000000000000
所以我们得到了相同的价值。因此无限递归。
如果你必须处理这种情况,这里有一个想法。在n<0
测试之前插入此内容:
if (n==-2147483648) return 1/(x*pow(x,2147483647));
显然这是对这一案件的黑客攻击。最终,您的问题域将决定最优雅/通用的解决方案。
答案 1 :(得分:2)
-2147483648是十六进制80000000是最大的负数,并且是最大的正数之一。所以当n = -2147483648时,没有-n。代码将在
行失败if(n<0) return 1/pow(x,-n);
这当然是一个特例。