簡體   English   中英

找到64位數的位置

[英]find ones position in 64 bit number

我試圖在64位數字中找到兩個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);

        }   
    }
}

線路上有兩個漏洞

if ((number & (1 << i))==1)

哪個應該讀

if (number & (1ull << i))

1更改為1ull意味着左移是在unsigned long long類型而不是int ,因此位掩碼實際上可以到達位置32到63.將比較刪除為1是因為number & mask的結果(其中mask只有一位設置)是mask0 ,當i為0時mask僅等於1。

但是,當我進行更改時,我的輸出為0 59 ,這仍然不是您所期望的。 剩下的問題是576460752303423489(十進制)= 0800 0000 0000 0001 (十六進制)。 0 59是該數字的正確輸出。 想要的號碼是9223372036854775809(十進制)= 8000 0000 0000 0001 (十六進制)。

順便說一句, main需要返回int ,而不是void ,並且需要顯式return 0; 作為它的最后一個動作(除非你使用返回代碼做一些更復雜的事情)。 是的,C99讓你省略。 無論如何要這樣做。

因為(1 << i)是您正在編譯和運行的平台上的32位int值。 這然后得到符號擴展到64位的&操作與所述number值,從而導致位31至63被復制成位32。

此外,您正在將&的結果& 1進行比較,這是不正確的。 如果該位置位則不為0,但不會為1。

將32位int移位32是未定義的。

此外,您的輸入數字不正確。 設置的位位於0和59位(如果您希望從1開始計數,則為1和60)。

修復是使用(1ull << i),或以其他方式右移原始值和&它為1(而不是左移1)。 當然,如果你用左移1和&它與原始值,結果將不是1(除了位0),所以你需要比較!= 0而不是== 1

#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 long常量。 第二個是在if語句中,你的意思是不與1進行比較,這對於最右邊的位只會是真的。

輸出: 0 59

這是正確的,因為576460752303423489等於0x800000000000001

通過采用將>>運算符應用於變量而不是文字的方法,首先可以避免這個問題:

if ((variable >> other_variable) & 1)
   ...

我知道這個問題有一些時間和多個正確的答案,而我應該是一個評論,但它有點太長了。 我建議你在宏中封裝位檢查邏輯,不要直接使用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);
}

可以使用編譯器工具以最有效的方式執行位分析任務(在許多情況下僅使用單個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

其他編譯器具有類似的機制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM