Reputation: 83
Why does this function give the wrong answer -1
rather than the right answer 1
when I try this? myPow(-1.00000, -2147483648)
double QuickPower(double x, int n)
{
if(n==0){
return 1;
}
if(n==1){
return x;
}
if(n>=2){
int res=n%2;
double half=QuickPower(x,n/2);
return res? Half*half*x: half*half;
}
}
double myPow(double x, int n) {
return n>=0? QuickPower(x,n):(1/QuickPower(x,-n));
}
I just try to run the code below. "Hello World" is printed out.
Here I did't specify data type but it still pass if statement. Why?
if (-1 > 2147483648)
{
cout << "Hello World";
}
Upvotes: 5
Views: 1280
Reputation: 772
C# Simple solution:
class Program
{
private static void Main(string[] args)
{
var result = MyPow(-1.00000, -2147483648);
}
public static double MyPow(double x, int n)
{
return Math.Pow(x, n);
}
}
after running this code, variable "result"'s value will equal to 1
Upvotes: 0
Reputation: 411
/*Java Solution */
class Solution {
public double myPow(double x, int n) {
if(n == 0) return 1;
if(Math.abs(x-0.0)<0.0000001) return 0.0;
if(Math.abs(x-1.0)<0.0000001) return 1.0;
if(n < 0) x = 1.0/x;
return Power(x, Math.abs(n));
}
double Power(double x, int n){
if(n == 0) return 1;
if(n == 1) return x;
return ((n&0x1) == 1) ? x*Power(x*x, n/2) : Power(x*x, n/2);
}
}
Upvotes: 0
Reputation: 5619
Note that Primitive data type ranges are:
short int and int: −32,768 to 32,767
unsigned short int and unsigned int: 0 to 65,535
long int: −2,147,483,648 to 2,147,483,647
unsigned long int: 0 to 4,294,967,295
long long int: −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Reference: MSDN and The GNU C Reference
As you can see, the minimum value an integer can hold is −2,147,483,648
, so when you perform -(−2,147,483,648)
an integer overflow occurred.
So use long long int
instead of int
to handle with big signed number.
The following code:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
double QuickPower(double x, long long int n)
{
if(n==0){
return 1;
}
if(n==1){
return x;
}
if(n>=2){
long long int res=n%2;
double half=QuickPower(x,n/2);
return res? half*half*x: half*half;
}
else
return 0;
}
double myPow(double x, long long int n) {
return n>=0? QuickPower(x,n):(1/QuickPower(x,-n));
}
int main () {
cout << myPow(-1.00000, -2147483648);
}
Give me output:
1
Upvotes: 3
Reputation: 73440
Your problem is due to integer overflow when calculating -n.
On your system (and my local one) INT_MIN
=-2147483648 and INT_MAX
=2147483647.
So the problem is that -(INT_MIN)
is not representable as an integer.
However you can avoid this issue without going to a higher precision integer type:
Since
xn = xn+1 / x = (1/x) / x-(n+1)
we can rewrite the myPow
as
double myPow(double x, int n) {
return n>=0? QuickPower(x,n):(1/x)/QuickPower(x,-(n+1));
}
This function is OK since -(INT_MIN+1)=INT_MAX
.
It's worth noting that this will have myPow(0,-k)
return either +/- Infinity (n=-1) or NaN (n<-1). If you need that case to be consistent then
a little more work is required. In general the handling of infinite / nan values is tricky for pow (and not "correct" in this, or the original implementation) - it is worth the man page for the C pow function to get all the edge cases.
Upvotes: 3
Reputation: 24417
The error is a result of an integer overflow.
Inside myPow
you negate n when n is negative.
Negating -2147483648 gives 2147483648, which is 1 more than the maximum positive signed 32 bit integer value, which is 2147483647. Use a larger integer data type to fix the bug.
Upvotes: 5