Modulo操作员在Java中给出了意外的输出



我在java中有以下操作方法:

/**
 * Determines if n is a power of z
 * 
 * @param z the number that n may be a power of
 * @param n the number that may be a power of z
 * @return true if n is a power of z 
 */
public boolean isPowerOf(int z, int n) {
    double output = Math.log(n) / Math.log(z);
    if(output % 1 > 0) {
        return false;
    } else {
        return true;
    }
}
isPowerOf(3, 729); //returns true, because 3^6 = 729

效果很好,但是我第一次尝试了不同的尝试:

public boolean isPowerOf(int z, int n) {
    double output = Math.log(n) % Math.log(z);
    if(output != 0) {
        return false;
    } else {
        return true;
    }
}

但是,对于log(729) % log(3),似乎返回1.0986122886681093,而log(729) / log(3) is 6的结果。

任何人都能告诉我是什么原因导致Modulo操作员仍然在此处给1.09剩余?

任何人都能告诉我是什么原因导致Modulo操作员仍然在这里剩下1.09?

基本上是正常的浮点不准确性。您使用的值不是 log(729)和log(3)。如果您查看log(3)log(729) % log(3),您会发现它们几乎完全相同:

public class Test {
    public static void main(String[] args) {
        double x = Math.log(729);
        double y = Math.log(3);
        System.out.println(x);
        System.out.println(y);
        System.out.println(x % y);
    }
}

输出:

6.591673732008658
1.0986122886681098
1.0986122886681093

换句话说,log(729)有效地是log(3) * 5.9999999999999(或类似的东西)。您可能希望在基本上为您的测试增加一些容忍度,并返回其余部分是否非常接近0 或非常接近log(z) 。。。P>

或者,使用log和Division"大致"计算功率应该是什么,然后Math.pow检查确切的值:

int power = (int) (Math.log(n) / Math.log(z) + 0.5);
return n == Math.pow(z, power);

在这里,您应该可以就浮点不准确而已,直到数字变得"很大"为止。如果您想精确地使用,则可以使用BigInteger

Math.log(729)  = 6.591673732008658
Math.log(3) = 1.0986122886681098
d= 1.0986122886681093

如果您注意到,d (1.0986122886681093)Math.log(3)-(1.0986122886681098)值稍小(最后一个数字),添加添加似乎正常。您可能缺少双重数据类型的精度理解。浮点号由于其实际表示形式而具有一些不准确的值。

相关内容

  • 没有找到相关文章

最新更新