web-dev-qa-db-ja.com

このビット単位の操作では、2のべき乗をどのようにチェックしますか?

私は些細なはずのコードを見ていますが、ここで私の数学は悲惨なことに失敗しています。

以下は、以下を使用して2のべき乗かどうかを確認する条件です。

if((num != 1) && (num & (num - 1))) { /* make num pow of 2 */ }

私の質問は、numとnum-1の間でビット単位のANDを使用すると、数値が2の累乗であるかどうかをどのように判断するのですか?

37
Coocoo4Cocoa

2マイナス1の累乗はすべて1です:([〜#〜] n [〜#〜] -1 = 111 .... b

2 = 2^1.  2-1 = 1 (1b)
4 = 2^2.  4-1 = 3 (11b)
8 = 2^3.  8-1 = 7 (111b)

例として8を取り上げます。 1000および0111 = 0000

そのため、この式は、数値が2の累乗でないかどうかをテストします。

91
eduffy

さて、最初のケースは2をチェックします == 1。

その他の場合、num & (num - 1)が作用します:

つまり、任意の数を取り、下位の1つからビットをマスクすると、次の2つの場合のいずれかが発生します。

  1. 数値が既に2のべき乗である場合、1つ少ないと、下位ビットのみが設定された2進数になります。 _&_を使用しても何も起こりません。

    • 8の例:0100 & (0100 - 1)-> _(0100 & 0011)_-> _0000_
  2. 数がすでに2の累乗でない場合、1つ少ない方が最上位ビットに触れないため、結果は少なくとも numより小さい2の最大のべき乗になります。

    • 3の例:0011 & (0011 - 1)-> _(0011 & 0010)_-> _0010_

    • 13の例:1101 & (1101 - 1)-> _(1101 & 1100)_-> _1100_

したがって、実際の表現は、2を含む2のべき乗ではないすべてを見つけます。

14
lavinio

上手、

x = 1000の場合、x-1 = 0111です。そして、1000 && 0111は0000です。

2の累乗である各数値Xには、位置xに1があるx-1があり、ゼロがあります。また、ビット単位の0と1は常に0です。

数値xが2の累乗でない場合、たとえば0110。x-1は0101であり、andは0100を返します。

0000-1111内のすべての組み合わせについて、これは

   X  X-1 X && X-1  
0000 1111 0000   
0001 0000 0000 
0010 0001 0000
0011 0010 0010
0100 0011 0000
0101 0100 0100
0110 0101 0100
0111 0110 0110
1000 0111 0000
1001 1000 1000
1010 1001 1000
1011 1010 1010
1100 1011 1000
1101 1100 1100
1110 1101 1100
1111 1110 1110

また、1を個別にチェックする必要はありません。

6
Toon Krijthe

説明 ここ うまく

また、与えられた式は、0が2の累乗であると見なします。これを修正するには、代わりに!(x & (x - 1)) && x;を使用します。

3
rohittt

整数が2のべき乗かどうかを決定します。 (x & (x-1))がゼロの場合、数値は2の累乗です。

たとえば、xを8(バイナリの1000)にします。その後、x-1 = 7(0111)。

if    1000
  &   0111
---------------
      0000

実証するCプログラム:

#include <stdio.h>

void main()
{
    int a = 8;
    if ((a&(a-1))==0)
    {
        printf("the bit is power of 2  \n");
    }
    else 
    {
        printf("the bit is not power of 2\n");
    }
}

これはthe bit is power of 2を出力します。

#include <stdio.h>

void main()
{
    int a = 7;
    if ((a&(a-1))==0)
    {
        printf("the bit is power of 2  \n");
    }
    else 
    {
        printf("the bit is not power of 2\n");
    }
}

これはthe bit is not power of 2を出力します。

1
sanjeev