c_cpp 总数没有。 A和B之间的2的补码表示中的1,包括在内。 Hackerrank的“2补”问题。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 总数没有。 A和B之间的2的补码表示中的1,包括在内。 Hackerrank的“2补”问题。相关的知识,希望对你有一定的参考价值。
#include <stdio.h>
#include <math.h>
#include <limits.h>
unsigned int prevTwo(unsigned int x) // bit twiddling
{
unsigned int y = x;
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
if(x != y)
x = x >> 1;
return x;
}
long long countOneZero(int n)
{
if(n == 0 || n == 1)
return n;
int k = prevTwo((unsigned int)n);
int p = 1, k2 = k;
while((k>>1) != 1)
{
k = k>>1;
p++;
}
return (long long)pow((double)2, p-1)*p + (n-k2+1) + countOneZero(n-k2);
}
long long countOnes(int a, int b)
{
if(a <= 0)
a = 1;
return countOneZero(b) - countOneZero(a-1);
}
int main()
{
int a, b, flag;
int t, T;
scanf("%d",&T);
for(t=0;t<T;t++)
{
flag = 0;
scanf("%d %d", &a, &b);
if(a == 0 && b == 0)
{
printf("%d\n",0);
continue;
}
if(a == 0)
a++;
if(b == 0)
b--;
if(a == INT_MIN && b == INT_MIN)
{
printf("%d\n",1);
continue;
}
if(a == INT_MIN)
{
flag = 1;
a++;
}
if(a < 0 && b < 0)
{
a = -a;
b = -b;
printf("%lld\n",(long long)32*(a-b+1)-countOnes(b-1,a-1) + flag);
}
else if(a > 0 && b > 0)
{
printf("%lld\n",countOnes(a,b));
}
else
{
a = -a;
printf("%lld\n",(long long)32*a-countOnes(1,a-1)+countOnes(1,b) + flag);
}
}
return 0;
}
以上是关于c_cpp 总数没有。 A和B之间的2的补码表示中的1,包括在内。 Hackerrank的“2补”问题。的主要内容,如果未能解决你的问题,请参考以下文章
数据的表示和运算-第二节2:补码加减运算器和标志位的生成
Q 格式使用总结
原码反码补码移码之间的关系和转换
C_基础编码(补码详解)
补码如何理解
(计算机组成原理)第二章数据的表示和运算-第二节1:定点数的表示(原码反码补码和移码)