Implement pow(x, n)

Implement pow(x, n)

本文关键字:pow Implement      更新时间:2023-10-16

为什么当我尝试这个函数时,这个函数-1给出错误的答案而不是正确的答案1myPow(-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));
}

我只是尝试运行下面的代码。"你好世界"被打印出来。在这里我没有指定数据类型,但它仍然传递 if 语句。为什么?
if (-1 > 2147483648) { cout << "Hello World"; }

该错误是整数溢出的结果。

myPow 内部,当 n 为负数时,您否定 n。

否定 -2147483648 得到 2147483648,比最大正有符号 32 位整数值(2147483647)多 1。使用较大的整数数据类型来修复该 bug。

您的问题是由于计算 -n 时整数溢出造成的。在您的系统(和我的本地系统)上,INT_MIN =-2147483648 和 INT_MAX =2147483647。

所以问题是-(INT_MIN)不能表示为整数。但是,您可以在不使用更高精度整数类型的情况下避免此问题:

因为

x n = x n+1/x = (1/x)

/x-(n+1)

我们可以将myPow重写为

double myPow(double x, int n) {
    return n>=0? QuickPower(x,n):(1/x)/QuickPower(x,-(n+1));
}

此功能自 -(INT_MIN+1)=INT_MAX 年以来是可以的。

值得注意的是,这将myPow(0,-k)返回+/- 无穷大(n = -1)或NaN(n<-1)。如果您需要该情况保持一致,那么还需要做更多的工作。一般来说,无限/nan 值的处理对于 pow 来说是棘手的(在这个或原始实现中不是"正确的")——C pow 函数的手册页来获取所有边缘情况是值得的。

请注意,基元数据类型范围为:

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

参考:MSDN 和 GNU C 参考

如您所见,整数可以容纳的最小值是 −2,147,483,648 ,因此当您执行-(−2,147,483,648)时,会发生整数溢出。

因此,请使用long long int而不是int来处理大符号数字。

以下代码:

#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);
}

给我输出:

1

/*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); 
}
}

C# 简单解决方案:

    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);
            }
        }

运行此代码后,变量"result"的值将等于 1