我正在尝试计算1 + 1 * 2 + 1 * 2 * 3 + 1 * 2 * 3 * 4 + ... + 1 * 2 * ... * n
,其中n
是用户输入。
它适用于n
最多12的值。我想计算n = 13
,n = 14
和n = 15
的总和。我如何在C89中做到这一点?据我所知,我只能在C99或C11中使用unsigned long long int
。
我的代码:
#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;
}
答案 0 :(得分:88)
实际上,您需要一些arbitrary precision arithmetic(a.k.a。 bigint 或 bignum )库。我的建议是GMPlib,但有other ones。
不要尝试编写自己的bignum库。高效的&amp;存在聪明的算法,但它们不直观且难以掌握(你可以找到专门讨论这个问题的全书)。此外,像GMPlib这样的现有库正在利用标准C编译器不会发出的特定机器指令(例如ADC -add with carry)(来自纯C代码)。
如果这是一个家庭作业并且您不允许使用外部代码,请考虑例如表示基数或radix 1000000000(十亿)的数字,并以非常幼稚的方式编写自己的操作,类似于你小时候学到了什么。但要注意存在更有效的算法(并且真正的bignum库正在使用它们)。
数字可以通过数组unsigned
表示为100000000,每个数组都是1000000000的“数字”。所以你需要管理数组(可能是使用malloc
分配的堆)和他们的长度。
答案 1 :(得分:20)
您可以使用double
,特别是如果您的平台使用IEEE754。
这样的double
给你53位精度,这意味着整数精确到2的第53次幂。这对于这种情况就足够了。
如果您的平台不使用IEEE754,请参阅所采用的浮点方案的文档。 可能就足够了。
答案 2 :(得分:0)
当你刚刚超过MaxInt的极限时,一个简单的方法是以10 ^ n为模拟计算合适的n,你做的计算与浮点计算相同,但你将所有内容除以10 ^ r。前一个结果将为您提供前n位数,而后一个结果将为您提供答案的最后一位数,并删除前r位数。那么由于舍入误差,这里的最后几位数字将是不准确的,所以你应该选择r小于n。在这种情况下,取n = 9和r = 5将很好地工作。