繁体   English   中英

如何求大数?

[英]How to sum large numbers?

我正在尝试计算1 + 1 * 2 + 1 * 2 * 3 + 1 * 2 * 3 * 4 + ... + 1 * 2 * ... * n其中n是用户输入。 它适用于n到12的值。我想计算n = 13n = 14n = 15的总和。 我该如何在C89中做到这一点? 据我所知,我只能在C99或C11中使用unsigned long long int

  1. 输入13,结果2455009817,预期6749977113
  2. 输入14,结果3733955097,预期93928268313
  3. 输入15,结果1443297817,预期1401602636313

我的代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    unsigned long int n;
    unsigned long int P = 1;
    int i;
    unsigned long int sum = 0;
    scanf("%lu", &n);
    for(i = 1; i <= n; i++)
    {
        P *= i;
        sum += P;
    }
    printf("%lu", sum);
    return 0;
}

实际上,您需要一些任意精度的算术库(又名bigintbignum )。 我的建议是GMPlib,但还有其他建议。

不要尝试编写自己的bignum库。 虽然存在高效且聪明的算法,但它们不直观且难以掌握(您可以找到有关该问题的整本书)。 另外,现有的库(例如GMPlib)正在利用标准C编译器不会发出的特定机器指令(例如ADC-带进位加法)(来自纯C代码)。

如果这是一项家庭作业,并且您不允许使用外部代码,请考虑使用一个数字表示基数或基数 1000000000(十亿),并以一种非常幼稚的方式为自己编写操作代码,类似于您从小就学到的方法。 但是请注意,存在更有效的算法(并且实际的bignum库正在使用它们)。

一个数字可以以1000000000为基数表示,它具有一个unsigned数组,每个数组都是以1000000000为基数的“数字”。因此,您需要管理数组(可能是使用malloc分配的堆)及其长度。

您可以使用double ,特别是如果您的平台使用IEEE754。

这样的double精度数为您提供53位精度,这意味着整数精确到2的53次幂。对于这种情况,这已经足够了。

如果您的平台不使用IEEE754,请查阅有关采用的浮点方案的文档。 可能就足够了。

当您刚刚超过MaxInt的极限时,一种简单的方法是对一个合适的n进行10 ^ n模的计算,并且您执行与浮点计算相同的计算,但是将所有内容除以10 ^ r。将为您提供前n位数字,而后一项结果将为您提供答案的最后几位数字,并删除前r位数字。 然后,由于舍入误差,此处的最后几位数字将不准确,因此您应选择小于n的ra位。 在这种情况下,取n = 9且r = 5会很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM