查找数字是否为2的幂,没有数学函数或日志函数

时间:2013-10-15 14:02:13

标签: java

我想查找用户输入的数字是否为2的幂。

我的代码不起作用。

public class power_of_two
{  
    public static void main(String args[])  
    {  

        Scanner in=new Scanner(System.in);
        System.out.println("Enter the number : ");
        int num = in.nextInt();

        int other = 1;  
        if(((~num) & 1) == 1)  
        {  
            System.out.println("The number is a power of two");  
        }  
        else  
        {
            System.out.println("The number is a  NOT A power of two");  
        }
    }  
} 

让我知道如何才能找到两个号码的力量 例如,8是2的幂 22 2的幂等等。

6 个答案:

答案 0 :(得分:197)

您可以测试正整数n是否为2的幂,类似

(n & (n - 1)) == 0

如果n可以是非正数(即负数或零),则应使用

(n > 0) && ((n & (n - 1)) == 0)

如果n确实是2的幂,那么在二进制中它将看起来像:

10000000...

所以n - 1看起来像

01111111...

当我们bitwise-AND时:

  10000000...
& 01111111...
  -----------
  00000000...

现在,如果n 不是 2的幂,那么除了前导1之外,其二进制表示还会有一些其他的1,这意味着{{1} }和n将具有相同的前导1位(因为如果在某处的二进制表示中有另一个1,则减去1不可能关闭此位)。因此n - 1操作如果&不是2的幂,则无法生成0,因为n &和{{1}的两个前导位}将自己产生n。这当然假设n - 1是正面的。

维基百科上的"Fast algorithm to check if a positive number is a power of two"也对此进行了解释。


快速健全检查:

1
1
2
4
8
16
32
64

答案 1 :(得分:93)

您可以使用bitwise AND (&) operator

return (num & -num) == num

为什么会这样?

考虑数字8,它是二进制的(假设是32位)?

0000 0000 0000 0000 0000 0000 0000 1000

现在让我们看看-8是如何表示的? 1

1111 1111 1111 1111 1111 1111 1111 1000

最后..让我们计算8 & -8

0000 0000 0000 0000 0000 0000 0000 1000   8
↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓   &
1111 1111 1111 1111 1111 1111 1111 1000  -8
---------------------------------------
0000 0000 0000 0000 0000 0000 0000 1000   8    ¯\_(ツ)_/¯

现在让我们再举一个例子,让我们说7,这是 2的力量。

0000 0000 0000 0000 0000 0000 0000 0111   7
↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓ ↓↓↓↓   &                       
1111 1111 1111 1111 1111 1111 1111 1001  -7
---------------------------------------
0000 0000 0000 0000 0000 0000 0000 0001  != 7  ¯\_(ة_ة)_/¯

如@arshajii所述,想想如果num为零会发生什么......我会为你留下解决方案:)

1 一个很好的方法来记住如何计算:从最右边的位开始,对于你看到的每个0,不要改变它,当你看到1,离开它并继续,但从现在开始,反转所有位。我试着更多地解释here

答案 2 :(得分:7)

double input = 22;

while(((input != 2) && input % 2 == 0) || input == 1) {
 input = input /2;
}

return input == 2;

继续将其除以2,直到达到1或奇数。如果它达到1则为2的幂,否则不是。

答案 3 :(得分:5)

直截了当的解决方案:

bool isPowerOfTwo(int n) {
    // All values < 1 cannot be (positive, at least) powers of two.
    if (n < 1) return false;

    // Keep shifting bits.
    while (n > 1) {
        // Since n > 1, the low bit set means at least two bits must
        // be set, making n no longer a power of two.
        if (n & 0x1) return false;
        // Throw away the bottom (zero) bit.
        n >>= 1;
    }
    // Only one bit was set, therefore, n is a power of two.
    return true;
}

当然,这并不像其他一些比特巧妙的解决方案(它确实非常聪明)那样最优,但它很容易看出它是如何工作的,并验证它是否适合您。

对于输入4,我们得到:

n = 4 (0x100)
run loop
n = 2 (0x10)
run loop
n = 1 (0x1)
return true

对于无效输入,例如5,我们得到:

n = 5 (0x101)
return false (0x101 & 0x1 => 0x1, which is truthy)

答案 4 :(得分:0)

   public boolean isPowerOfTwo(int n){

            boolean isPower=false;
            int temp=n;

            while(temp>=2){
                if(temp%2==0){
                    isPower=true;

                }else{
                    isPower=false;
                    break;
                }
                temp=temp/2;
            }

            if(isPower){
                System.out.println("power of 2");
            }else{
                System.out.println("not power of 2");
            }

            return isPower;
        }

答案 5 :(得分:-2)

一个非常简单的解决方案。

int n = 8; // any integer and you can take it from user also
for(;n>0;n++){
    if(n%2 != 0) {
        System.out.println("not a power of two")
        return;
    } // if ends here
    n = n/2;
}// for ends here
System.out.println("power of two")