功率为2,试图达到2 ^ 1000,分段故障

时间:2010-09-08 17:23:50

标签: c

我正在构建一个将乘以2的程序,并获得长准确的数字。 在这里,我构建了一个程序,其中每个数字都存储在一个不同的变量中。 当我编译程序时,我键入2 ^ 63,它给了我正确的答案。 但是当我键入2 ^ 64时,我得到一个“分段错误”。

这是什么?我该怎么办?

#include <stdio.h>
int main(void)
{
  printf("2^n, enter n: ");
  int n, array = 1;

  scanf("%d", &n);
  int num[array];

  num[0] = 2;
  int remainder = 0;
  if (n > 1) {
    int counter = 0;
    int counter3 = 1;

    for (counter3 = 1; counter3 < n; counter3++) {
      remainder = 0;

      for (counter = 0; counter < array; counter++) {
        num[counter] *= 2;
        num[counter] += remainder;
        remainder = 0;

        if (num[counter] / 10 != 0) {
          remainder = num[counter] / 10;
          num[counter] -= remainder * 10;
          if (counter+1 >= array) {
            array++;
            num[counter+1] = remainder;
            remainder = 0;
            break;
          }
        }
      }
    }
  }

  int counter2;
  for (counter2 = array - 1; counter2 >= 0; counter2--)
    printf("%d", num[counter2]);

  putchar('\n');
  return 0;
}

5 个答案:

答案 0 :(得分:3)

我认为你的问题是

int num[array];

这是一个静态数组,一旦声明它的大小为1(数组= 1只上面几行),那就是数组的大小。

大数据库非常复杂,最好留给第三方库。

尝试查看GMP

如果您必须自己动手,请尝试使用动态数组类,如std :: vector

答案 1 :(得分:2)

这是因为存储2 ^ n你需要一个n位类型 - 通常可用于n&lt; 64,但不是高于此数字。

您需要的是通用的第三方大型整数库。

答案 2 :(得分:2)

num只能包含1个整数。 你很幸运int num[1]在一个页面(?)上,在访问num[64]导致分段错误之前,为64个整数(256个字节)提供了空间。

您可以使用int*并根据需要重新分配它以存储新位...

答案 3 :(得分:1)

其他人或多或少地回答了这个问题,所以我会做一些不同的事情:我将在这里粘贴你的程序的完整修订版。我修复了你问的bug,但我也做了很多其他的修改。我希望您仔细阅读修订后的程序,并考虑为什么我改变了某些事情。

// Note: This program uses C99 features; must be compiled with e.g.
// -std=c99 (for GCC).  Nonetheless it is C, not C++.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

static void
printdigits(const int num[], int top)
{
  for (int i = top - 1; i >= 0; i--) {
    assert(0 <= num[i] && num[i] < 10);
    putchar('0' + num[i]);
  }
  putchar('\n');
}

int
main(int argc, char **argv)
{
  if (argc != 2) {
    fprintf(stderr, "usage: %s n\ncomputes 2^n\n", argv[0]);
    return 1;
  }

  char *eptr;
  long n = strtol(argv[1], &eptr, 10);
  if (eptr == argv[1] || *eptr != '\0') {
    fprintf(stderr, "%s: '%s' is not a number\n", argv[0], argv[1]);
    return 1;
  }

  if (n < 1) {
    fputs("n must be at least 1\n", stderr);
    return 1;
  }

  unsigned int num[n]; // could be short or even char, but memory is not tight
  int top = 1;
  num[0] = 2;

  for (int i = 1; i < n; i++) {
    int carry = 0;
    for (int j = 0; j < top; j++) {
      num[j] = num[j] * 2 + carry;
      carry = 0;

      if (num[j] >= 10) {
        assert(num[j] < 20); // largest possible is 2*9+1 = 19
        carry = 1;
        num[j] -= 10;

        if (j+1 >= top) {
          assert(top < n);
          num[j+1] = carry;
          top++;
          break;
        }
      }
    }

#ifndef NDEBUG
    printf("Iteration %d: top=%d num=", i, top);
    printdigits(num, top);
#endif
  }

#ifndef NDEBUG
  putchar('\n');
#endif
  printdigits(num, top);
  return 0;
}

答案 4 :(得分:0)

即使您的解决方案是在C语言中,您也可以使用其他语言来解决项目问题,因为项目euler与语言无关。我使用C来解决很多问题,当遇到大整数问题时,我倾向于使用python,因为它可以处理大量的操作/操作/计算。

修改
将问题中的示例代码指定为C而不是C ++。