Modulo operator gives unexpected output in Java

floating-accuracy, java, mathematical-optimization, modulo

Solution

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

The normal floating point inaccuracies, basically. The values you're using aren't exactly log(729) and log(3). If you look at `log(3)` and `log(729) % log(3)` you'll see they're almost exactly the same:

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

Output:

6.591673732008658
1.0986122886681098
1.0986122886681093

In other words, `log(729)` is effectively `log(3) * 5.9999999999999` (or something similar). You'll probably want to add some tolerance to your test, basically, and return whether or not the remainder is very close to 0 or very close to the `log(z)`.

Alternatively, use `log` and division to work out "roughly" what the power should be, then `Math.pow` to check for the exact value:

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

Here you should be okay in terms of floating point inaccuracies until the numbers get "pretty big". You can use `BigInteger` if you want to cope with very big numbers precisely.

Problem

I have the following, working method in 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 ``` Works fine n mighty, but I tried it differently the first time: ``` public boolean isPowerOf(int z, int n) { double output = Math.log(n) % Math.log(z); if(output != 0) { return false; } else { return true; } } ``` However, for `log(729) % log(3)` seems to return `1.0986122886681093`, while the outcome of `log(729) / log(3) is 6`. Anyone able to tell me what causes the modulo operator to still give `1.09` remainder here?

Original source