简体   繁体   English

有人可以在计算二进制表示形式的1时发现错误吗?

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

This code is outputting 0 for all values other 1. For 1 it is outputting 1. It looks like it is the executing the else statement because "temp" value is not being printed (All extra print statements have been added for debugging). 这段代码为所有其他1值输出0。对于1,它输出1。由于未打印“ temp”值,它似乎正在执行else语句(已添加所有其他print语句用于调试)。 Please help. 请帮忙。

#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;
}

So, you want to calculate a population count on a binary number? 因此,您要计算二进制数上的人口数吗?
What's wrong with 怎么了

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;
}

If you should find this too slow, you could go with the appropriate section of "bit twiddling hacks" (google it yourself, or search on this site). 如果您觉得这太慢了,则可以选择“ bit twiddling hacks”的相应部分(您自己搜索或在此网站上搜索)。 Or, you know, look up compiler intrinsics that do it in one cycle. 或者,您知道查找一个周期内完成的编译器内部函数。 Intel x86(-64): 英特尔x86(-64):

int64_t _mm_popcnt_u64(unsigned __int64 a);

gcc: gcc:

int __builtin_popcountll(unsigned long long)

pow is a floating-point function. pow是浮点函数。 So apart from being horrifically slow, pow (2, 30) may have rounding errors that make it a bit smaller than 2 raised to the power of 30, and assigning it to a long long will round it down to 0x3fffffff instead of 0x40000000. 因此,pow(2,30)除了令人发指的缓慢外,还可能具有舍入误差,使其略小于2的幂数,即30的幂,将其分配为long long会将其舍入为0x3fffffffff而不是0x40000000。 On the other hand, (1ll << 30) will be evaluated at compile time, and is guaranteed to give the correct result. 另一方面,(1ll << 30)将在编译时求值,并保证给出正确的结果。

check is never modified in the loop, which is why it doesn't work. 检查从未在循环中修改过,这就是为什么它不起作用的原因。

How many bits would you say are set in the number -1? 您会说数字-1设置了多少位?

How many bits would you say are set in the number 1234567890123456? 您会说数字1234567890123456中设置了多少位? Why wouldn't you give the right result for that number? 您为什么不为该数字给出正确的结果?

I'd say you need a bit of practice to find the most direct and simplest way to solve a problem. 我想您需要一些实践才能找到解决问题的最直接,最简单的方法。

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

That's the straightforward way to do it. 这是简单的方法。 You should really use unsigned, not signed for that kind of operation. 您应该真正将unsigned而不是signed用于此类操作。 There are clever tricks that give you faster code, but not what I would expect anyone to figure out on their own. 有一些巧妙的技巧可以为您提供更快的代码,但我却不希望有人自己弄清楚。

The problem is that check is never updated in the for loop. 问题是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;
    }
} 

temp is set using check every time, but since check doesn't change, neither does temp . 每次都会使用check来设置temp ,但是由于check不会改变,因此temp都不会更改。 Either switch it to temp /= 2; 将其切换为temp /= 2; , or use check instead of temp . ,或使用check代替temp

The main error is that your recursive function is not working. 主要错误是您的递归函数不起作用。 Try to take a close look: 尝试仔细看看:

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);
        }
    }
}

If suppose p=6 then your temp is 2^30 clearly p is less than temp. 如果假设p = 6,则您的温度为2 ^ 30,显然p小于温度。 So your recursion doesn't work. 因此,您的递归无效。 The statement: 该声明:

result=1+binarysum(p-temp);

never executes. 永远不会执行。 So you get result as zero because zero is the garbage value stored in the variable result . 因此您将result设为零,因为零是存储在变量result的垃圾值。 if you change your code to: 如果将代码更改为:

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);
        }
    }
}

Here is easy way to solve your problem 这是解决问题的简便方法

#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