簡體   English   中英

有人可以在計算二進制表示形式的1時發現錯誤嗎?

[英]Can someone find the error in calculating number of 1's in binary representation?

這段代碼為所有其他1值輸出0。對於1,它輸出1。由於未打印“ temp”值,它似乎正在執行else語句(已添加所有其他print語句用於調試)。 請幫忙。

#include<stdio.h>
#include<math.h>
int binarysum(long long int p);
int main(){
    int r;
    long long int x;
    scanf("%lld",&x);
    r=binarysum(x);
    printf("%d",r);
    return 0;
}
int binarysum(long long int p){
    int result;
    int j;
    long long int check=pow(2,30),temp;
    printf("%lld p %lld check\n",p,check);
    if(p==0)
        result=0;
    else if(p==1)
        result=1;
    else{
        for(j=31;j>=2;j--){
            temp=check/2;
            if(p>=temp){
                printf("%lld temp\n",temp);
                result=1+binarysum(p-temp);
                break;
            }
        } 
    }
    printf("%d result\n",result);
    return result;
}

因此,您要計算二進制數上的人口數嗎?
怎么了

int popcount(unsigned long long a)
{
    int retval = 0;
    size_t i;
    unsigned long long b = 1;
    for (i = 0; i<(CHAR_BIT*sizeof(unsigned long long); i++)
    {
        if (a & b<<i)
           retval++;
    }
    return retval;
}

如果您覺得這太慢了,則可以選擇“ bit twiddling hacks”的相應部分(您自己搜索或在此網站上搜索)。 或者,您知道查找一個周期內完成的編譯器內部函數。 英特爾x86(-64):

int64_t _mm_popcnt_u64(unsigned __int64 a);

gcc:

int __builtin_popcountll(unsigned long long)

pow是浮點函數。 因此,pow(2,30)除了令人發指的緩慢外,還可能具有舍入誤差,使其略小於2的冪數,即30的冪,將其分配為long long會將其舍入為0x3fffffffff而不是0x40000000。 另一方面,(1ll << 30)將在編譯時求值,並保證給出正確的結果。

檢查從未在循環中修改過,這就是為什么它不起作用的原因。

您會說數字-1設置了多少位?

您會說數字1234567890123456中設置了多少位? 您為什么不為該數字給出正確的結果?

我想您需要一些實踐才能找到解決問題的最直接,最簡單的方法。

int bitcount = 0; 
for (long long mask = 1ll << 62; mask != 0; mask >>= 1)
    if ((p & mask) != 0)
        ++bitcount;

這是簡單的方法。 您應該真正將unsigned而不是signed用於此類操作。 有一些巧妙的技巧可以為您提供更快的代碼,但我卻不希望有人自己弄清楚。

問題是check永遠不會在for循環中更新。

for(j=31;j>=2;j--){
    temp=check/2;
    if(p>=temp){
        printf("%lld temp\n",temp);
        result=1+binarysum(p-temp);
        break;
    }
} 

每次都會使用check來設置temp ,但是由於check不會改變,因此temp都不會更改。 將其切換為temp /= 2; ,或使用check代替temp

主要錯誤是您的遞歸函數不起作用。 嘗試仔細看看:

if(p==0)
    result=0;
        else if(p==1)
    result=1;
else{
    for(j=31;j>=2;j--){
        temp=check/2;
        printf("temp=%lld\n",temp);
        if(p>=temp){
            printf("%lld temp\n",temp);
            result=1+binarysum(p-temp);
        }
    }
}

如果假設p = 6,則您的溫度為2 ^ 30,顯然p小於溫度。 因此,您的遞歸無效。 該聲明:

result=1+binarysum(p-temp);

永遠不會執行。 因此您將result設為零,因為零是存儲在變量result的垃圾值。 如果將代碼更改為:

else{
    temp=check;
    for(j=31;j>=2;j--){
        temp=temp/2;
        printf("temp=%lld\n",temp);
        if(p>=temp){
            printf("%lld temp\n",temp);
            result=1+binarysum(p-temp);
        }
    }
}

這是解決問題的簡便方法

#include<stdio.h>
int main(){
    long long number;
    scanf("%lld",&number);
    int result=0;
    while(number>0){
        if(number&1){
            result++;
        }
        number=number>>1;
    }
    printf("%d\n",result);
}

暫無
暫無

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

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