java - 模运算符在 Java 中给出意外的输出

标签 java mathematical-optimization modulo floating-accuracy

我有以下 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

效果很好 n 强大,但我第一次尝试了不同的方法:

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) 的结果是 6

谁能告诉我是什么导致模运算符在这里仍然给出 1.09 余数?

最佳答案

Anyone able to tell me what causes the modulo operator to still give 1.09 remainder here?

基本上是正常的 float 不准确。您使用的值不是完全 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)

或者,使用 log 和除法“粗略地”计算出幂应该是多少,然后使用 Math.pow 检查准确值:

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

在数字变得“相当大”之前,在浮点不准确方面你应该没问题。如果您想精确处理非常的大数字,您可以使用BigInteger

关于java - 模运算符在 Java 中给出意外的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13031780/

相关文章:

java - 第一个数小于第二个数时的模数除法

java - DateUtils 使用哪个时区?

Java 正则表达式

Java 8 通过签名推断方法引用解析,这是否损坏?

java - 如何安排任务运行一次?

python - 解释 scipy 的 line_search 中的 amax 参数

r - 在 R 的 ompr 包中,如何重新表述我的目标/约束/变量以避免 "problem too large"错误?

python - 用参数最小化功能

data-structures - 哈希表是如何工作的?

python - 为什么每次迭代都必须执行取模?