c - C 中的 10000 阶乘

标签 c factorial

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

struct node;
typedef struct node* PtrToNode;

struct node {
  long long n;
  PtrToNode next;
};

PtrToNode factorial(int n, PtrToNode init);
void multiply(long long n, PtrToNode init, long long carry);

int main() {
  int n;
  while (1) {
    scanf("%d", &n);
    if (n > 0) {
      break;
    } else if (n == 0){
      printf("1\n");
      return 0;
    } else {
      printf("Retry.\n");
    }
  }
  PtrToNode init = malloc(sizeof(struct node));
  init->n = 1;
  init->next = NULL;
  PtrToNode head = factorial(n, init);
  PtrToNode tail = reverse(head);
  PtrToNode backup = tail;
  printf("%lld", tail->n);
  tail = tail->next;
  while(tail != NULL) {
    printf("%04lld", tail->n);
    tail = tail->next;
  }
  PtrToNode t;
  while (backup != NULL) {
    t = backup;
    backup = backup->next;
    free(t);
  }
}


PtrToNode factorial(int n, PtrToNode init) {
  for (int i = 1; i <= n; i++)
    multiply(i, init, 0);
  return init;
}

void multiply(long long n, PtrToNode init, long long carry) {
  long long temp = n * init->n + carry;
  init->n = temp % 10000;
  carry = temp / 10000;
  if (init->next != NULL) {
    multiply(n, init->next, carry);
  } else if (carry > 0) {
    init->next = malloc(sizeof(struct node));
    init->next->n = carry;
    init->next->next = NULL;
  } else {
    return;
  }
}

这是我计算10000阶乘的函数,对比网上资料我算出了正确答案。但是,当我将 n 的范围限制为 [0.999] 时,我什至无法计算 2000 阶乘。为什么当我将n'范围转换为[0, 9999]时,它可以计算出2000!甚至 10000!?

最佳答案

将数字簇限制为三位数的问题在于,将三位数乘以大于 1,000 的值可能会产生进位到四位数。

虽然这不会立即产生问题,但随着您将值沿计算链向上传递,错误会累积。 2000的结果有5000多位!进位溢出肯定会在结果中产生一个可见的错误。这发生在计算 2000! 的第 1258 步左右。

这不会发生在四位数的簇和 10,000 上,因为进位可以“溢出”到下一个数字的唯一地方是最后一个簇的计算,并且 long long 有很多足够的空间来容纳它而不会溢出。

关于c - C 中的 10000 阶乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32742716/

相关文章:

c - 在 C 中使用 %u 和 %d 打印内存地址的区别?

c - 数组不会使用指针在 C 中反向打印

c - 为什么这个阶乘计算不正确?

java - 5!是 120,但输出为 1!是120?

c - 需要左值作为赋值的左操作数

c - 基本 C 指针和函数

c - 定时函数调用成本

c - 如何在C编程中获得以下输出

python - 我不知道如何找到数字的阶乘。谁能帮我用递归和顺序编程来做到这一点?