In the following (naive) implementation of a pow(x, n)
method, ignoring completely any optimized approach, I find the following problem:
public double pow(double x, int n) {
boolean negative = n < 0;
long power = Math.abs(n);
double ans = 1.0;
for(long i = 0; i < power; i ) {
ans = ans * x;
}
return negative ? 1.0/ans: ans;
}
Here I have made the assumption that for the case of negative exponent I simply calculate the x^n
and then return 1/(x^n)
since e.g. 2^(-3) = 1/(2^3)
Problem:
The code fails in the following case:
pow(2.00000, -2147483648)
The output is 1.00000
while the expected correct result is 0.00000
If I change the code as follows:
public double pow(double x, int n) {
long power = n;
if(power < 0) {
x = 1 / x;
power = -power;
}
double ans = 1.0;
for(long i = 0; i < power; i ) {
ans = ans * x;
}
return ans;
}
The result is correct!
So what is the difference between doing the approaches? I was expecting them to be equivalent but they are not
CodePudding user response:
Math.abs(n)
is still an int
, and only afterwards it is assigned to a long
, Therefore, the absolute value of -2147483648
was -2147483648
again (this is noted in the documentation of Math.abs(int)
). With the negative bound, the loop performed no iterations.
Math.abs((long)n)
would work around that issue.