以Integer.MIN_VALUE为指数的Java pow实现



我正在Java中实现一个pow函数,我想知道我们如何处理Integer.MIN_VALUE作为指数?我们只是将其视为特例吗?

因为我试图将结果与标准的Java.lang.Math API进行比较,我得到了几个不同的结果。以下是比较列表

//this will print "1.0 vs 0.0"
System.out.println(pow(2,Integer.MIN_VALUE) + " vs " + Math.pow(2,Integer.MIN_VALUE));
//this will print "1.0 vs 1.0"
System.out.println(pow(1,Integer.MIN_VALUE) + " vs " + Math.pow(1,Integer.MIN_VALUE));
public double pow(double base, int exp){
     double result = 1.0;
     boolean pos = false;
     if(exp == 0) return result;
     if(exp > 0){
         pos = true;
         exp *= -1;
     }
     while(exp > 0){
        if((exp & 1) == 1){
           result *= base;
        }
        base *= base;
        exp /= 2;
     }
     if(!pos){
        result = 1/result;
     }
     return result;
}

所以我想知道Integer.MIN_VALUE是否是一种特殊情况,我必须有一个 if 语句来检查它。

  if(exp == Integer.MIN_VALUE && base > 1) return 0.0;

基于这一行:

exp *= -1;

看来可能必须是一个特例。当然有一些方法可以在没有这种特殊情况下实现这一点,但是由于-1 * Integer.MIN_VALUE不能存储在 int 中,如果不单独处理它,您会收到一个错误。

是的,你遇到了Integer.MIN_VALUE * -1 == Integer.MIN_VALUE的问题。 你可以把它特例化,也可以用另一种方式处理它。 事实上,一种可能的解决方案是在exp为正时将其设为负数,而不是相反;您只需使用-exp而不是exp

在我的系统上,我有

-2147483648
2147483647

分别适用于Integer.MIN_VALUEInteger.MAX_VALUE。 所以你应该在行中看到问题

exp *= -1;

好吧,真正的问题是,由于符号不会在MIN_VALUE上翻转,因此符号会级联到 exp/2。 "负功率"情况适用。如果我们拆分它,它会更容易:

    public double myPow(double x, int n) {
    double result = 1.00000;
    boolean negative = false;
    
    if(n <0) {
        negative = true;
        n= -n;
    }
    
    result=power(x,n);
    if(negative) {
        result = 1/result;
    }
    return result;
}
private double power(double a, int n) {
    if(n ==0 || a==1) return 1;// a^0 = 1, 1^n = 1
    double x=power(a,n/2);
    
    if(n%2 == 0) return x*x;
    else return a*x*x;
}

最新更新