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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With