I'm googling about how to find if a number y
is power of x
and came across this link
Java
public class Solution { public boolean isPowerOfThree(int n) { return (Math.log10(n) / Math.log10(3)) % 1 == 0; } }
Common pitfalls
This solution is problematic because we start using doubles, which means we are subject to precision errors. This means, we should never use
==
when comparing doubles. That is because the result ofMath.log10(n) / Math.log10(3)
could be5.0000001
or4.9999999
. This effect can be observed by using the functionMath.log()
instead ofMath.log10()
.In order to fix that, we need to compare the result against an
epsilon
.Java
return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
There I didn't understand return (Math.log(n) / Math.log(3) + epsilon) % 1 <= 2 * epsilon;
What is the meaning of that line?
Why EPSILON
is used while comparing floating points?
As the quoted section says, because of floating point imprecisions, you can have two numbers that should be exactly equal (if the calculations that created them were carried out with mathematical exactness), but that are instead slightly different.
When you compare them, you want to account for that slight difference and still treat numbers as equal if they differ only by a small amount, called epsilon.
How to choose an appropriate epsilon, though, is a tricky question and highly dependent on the nature of your calculations. I suppose that for this reason, Java does not include a "standard" epsilon constant (some other languages do).