javaalgorithmmath

LeetCode 231: Problem in finding whether a given number is Power of 2


I want to find whether a given number is a power of two in a mathematical way, not with a bitwise approach. Here is my code:

private static double logBaseTwo(final double x) {
    return Math.log(x) / Math.log(2);
}

private static double roundToNearestHundredThousandth(final double x) {
    return Math.round(x * 100000.0) / 100000.0;
}

private static boolean isInteger(final double x) {
    return (int)(Math.ceil(x)) == (int)(Math.floor(x));
}

public static boolean isPowerOfTwo(final int n) {
    return isInteger(roundToNearestHundredThousandth(logBaseTwo(n)));
}

It incorrectly returns true for certain numbers, such as 524287. Why is that?


Solution

  • Your code fails because you may need more precision than you allow to capture the difference between the logs of BIG_NUMBER and BIG_NUMBER+1

    The bitwise way is really best, but if you really want to use only "mathy" operations, then the best you can do is probably:

    public static boolean isPowerOfTwo(final int n) {
       int exp = (int)Math.round(logBaseTwo(n));
       int test = (int)Math.round(Math.pow(2.0,exp));
       return test == n;
    }
    

    This solution does not require any super-fine precision, and will work fine for all positive ints.