Can anyone tell me what makes the modulo operator still give 1.09 remainder here?
Common floating point inaccuracies, mostly. The values you use do not exactly match log (729) and log (3). If you look at log(3) and log(729) % log(3) , you will see that they are 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) effectively log(3) * 5.9999999999999 (or something similar). You will probably want to add tolerance to your test, basically, and return if the remainder is very close to 0 or very close to log(z) .
Alternatively, use log and division to work out “roughly” what should be valid, and then Math.pow to check the exact value:
int power = (int) (Math.log(n) / Math.log(z) + 0.5); return n == Math.pow(z, power);
Here you should be fine in terms of floating point inaccuracies until the numbers get “pretty big”. You can use BigInteger if you want to handle very large numbers accurately.
source share