[英]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.