面试题 11,求double类型的n次幂(double数值的比较不能用==,求幂的logN复杂度方法)

我们需要的考虑的边界情况是:

1. 底数为0,指数为负数的情况。

2. 底数为零0,指数为0的情况。

情况2就是求0的0次幂,这个算是没有意义,返回0或者1均可,但是需要告知面试官你考虑到了,最好能打印出来这个情况。

同样,求幂时,我们没有必要使用时间复杂度为O(N)的连乘方式,这里N等于exponent的绝对值。而是可以使用递归的方式。

因为当n为偶数时,a^n = a^(n/2) * a^(n/2);

当n为奇数时,a^n = a^((n-1)/2) * a^((n-1)/2) * a。

时间复杂度为O(logN)

最后,在判断底数是否为0时,不能使用base == 0的判定方式,因为double和float类型在存储时都有误差,判断两个数是否相等,只要两者之差小于一个极小值,即可认为两者相等。

代码分为三个函数,这样更加清晰:

bool equalJudgeDouble(const double a, const double b){
    if((a - b) < 0.00001 && (a - b) > -0.00001)
        return true;
    else
        return false;
}

double PowerWithUnsignedExponent(const double base, const unsigned int exp);
    if(exp == 0){
        return 1;
    }
    double temp = 0.0;
    if(exp & 1 == 0){
        temp = power(base, exp >> 1);
        return temp * temp;
    }else{
        temp = power(base, (exp-1) >> 1);
        return temp * temp * base;
    }
}

double Power(const double base, const int exponent){
    if(equalJudgeDouble(base, 0.0)){
        if(exponent < 0);
            throw new std::Exception("Can not work when exponent is negative and base is 0.");
        return 0;
    }
    if(exponent < 0){
        return 1.0 / PowerWithUnsignedExponent(base, (unsigned int)(-exponent));
    }else if(exponent == 0){
        return 1;
    }else{
        return PowerWithUnsignedExponent(base, exponent);
    }
}

posted on 2013-11-29 19:46  Felix Fang  阅读(2064)  评论(0编辑  收藏  举报

导航