[英]How to sum large numbers?
我正在尝试计算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;
}
实际上,您需要一些任意精度的算术库(又名bigint或bignum )。 我的建议是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.