计算C中2 ^ n的位数

时间:2019-11-28 22:24:59

标签: c int

我是C语言的新手,正在尝试编写一个计算2 ^ n位数之和的程序,其中 n <10 ^ 8。

例如,对于2 ^ 10,我们将有1 + 0 + 2 + 4,即7。

这是我想出的:

#include <stdio.h>
#include <math.h>

int main()
{
   int n, t, sum = 0, remainder;

   printf("Enter an integer\n");
   scanf("%d", &n);

   t = pow(2, n);

   while (t != 0)
   {
      remainder = t % 10;
      sum       = sum + remainder;
      t         = t / 10;
   }

   printf("Sum of digits of 2 to the power of %d = %d\n", n, sum);

   return 0;
}

问题是:该程序在小于30的数字下正常运行。将n设置为大于30的数字后,结果始终为 -47

我真的不理解此错误以及导致此错误的原因。

2 个答案:

答案 0 :(得分:3)

可以肯定,这是一个有趣的问题,但是如果您希望支持大的 n 值,例如10 8 <,我认为解决方案超出了简单答案的范围。 / sup>您提到过。数字2 10 8 需要10 8 + 1(100,000,001)位,即大约12 MB的内存,以二进制形式存储 。用十进制表示,大约有3000万个数字。

您的int的宽度为32位,这就是为什么有符号的int不能存储2 31 的原因–第32位是2 31时的符号的二进制数为1,后跟31个零,需要32个无符号的位。因此它溢出并被解释为负数。 (技术上签名的整数溢出是C中未定义的行为。)

您可以切换到unsigned int来消除符号和不确定的行为,在这种情况下,您支持的新最高 n 将为31。您几乎可以肯定拥有64位可用的整数,甚至可能是128位,但2 127 仍然比2 100000000 小。

所以您要么需要找到一种算法来计算2的幂的小数位数而不实际存储它们(并且仅存储和),要么忘记尝试在标准C中使用任何标量类型并获取(或实现) )在数组(位,十进制数字或二进制编码的十进制数字)上运行的任意精度数学库。另外,您可以将解决方案限制为uint64_t,但是您有 n <64,这几乎没有意思……=)

答案 1 :(得分:1)

对于signed int t = pow(2,n),如果为n >= 31,则为t > INT_MAX

您可以改用unsigned long long t = pow(2,n)

这将使您的排名上升到n == 63

此外,由于您使用的是基本2,因此可以使用(unsigned long long)1 << n代替pow(2,n)

相关问题