26

64 ビット数で 2 つの 1 の位置を見つけようとしています。この場合、それらは 0 番目と 63 番目の位置にあります。ここのコードは 0 と 32 を返しますが、これは半分しか正しくありません。これが機能しないのはなぜですか?

#include<stdio.h>
void main()
{
unsigned long long number=576460752303423489;
int i;
for (i=0; i<64; i++)
    {
    if ((number & (1 << i))==1)
        {
        printf("%d  ",i);

        }   
    }
}
4

6 に答える 6

4
#include<stdio.h>
int main()
{
    unsigned long long number = 576460752303423489;
    int i;
    for (i=0; i<64; i++)
    {
        if ((number & (1ULL << i)))   //here
        {
            printf("%d  ",i);    
        }   
    }
}

まず、定数1ULLを表すために使用します。unsigned long long2番目はifステートメントにあります。あなたが意味するのは、と比較しないこと1です。これは、右端のビットにのみ当てはまります。

出力:0 59

576460752303423489等しいので正解です。0x800000000000001

于 2013-09-18T15:31:50.610 に答える
1

>>この問題は、演算子をリテラルではなく変数に適用する方法を採用することで、最初から回避できたはずです。

if ((variable >> other_variable) & 1)
   ...
于 2013-09-18T19:11:16.070 に答える
0

私はコメントである必要がある間、質問にはいくつかの時間と複​​数の正解があることを知っていますが、それには少し長すぎます。ビット チェック ロジックをマクロにカプセル化し、64 の数値を直接使用せずに計算することをお勧めします。ビット操作ハックの非常に包括的なソースについては、こちらをご覧ください。

#include<stdio.h>
#include<limits.h>

#define CHECK_BIT(var,pos) ((var) & (1ULL<<(pos)))

int main(void)
{
    unsigned long long number=576460752303423489;
    int pos=sizeof(unsigned long long)*CHAR_BIT-1;    
    while((pos--)>=0) {
        if(CHECK_BIT(number,pos))
            printf("%d ",pos);
    }
    return(0);
}
于 2013-09-18T18:57:03.677 に答える
0

ビット操作に頼るのではなく、コンパイラ機能を使用して最も効率的な方法でビット分析タスクを実行できます (多くの場合、単一の CPU 命令のみを使用します)。

たとえば、gcc と clang はこれらの便利なルーチンを提供します。

__builtin_popcountll() - number of bits set in the 64b value
__builtin_clzll() - number of leading zeroes in the 64b value
__builtin_ctzll() - number of trailing zeroes in the 64b value
__builtin_ffsll() - bit index of least significant set bit in the 64b value

他のコンパイラにも同様のメカニズムがあります。

于 2013-09-19T04:12:37.553 に答える