使用此数组代码无法获得非常大的金额

  • 本文关键字:非常 金额 数组 代码 c
  • 更新时间 :
  • 英文 :


我面临的一个问题是,我需要将一些数组作为输入,然后将它们的和作为输出。但不幸的是,我在这里得到了令人担忧的结果。有人能解释一下这个代码出了什么问题吗?

#include<stdio.h>
int main()
#define N size
{
int size,i,sum=0;;
scanf("%d",&size);
int a[N];
for(i=0; i<size; i++)
{
scanf("%d", &a[i]);
}
for(i =0; i<size; i++)
{
sum = a[i] + sum;
}
printf("%d",sum);
return 0;
}

结果:

Input (stdin)
5
1000000001 1000000002 1000000003 1000000004 1000000005
Your Output (stdout)
705032719
Expected Output
5000000015

你提到你的结果是错误的,但当我在我的机器上尝试时,我得到了类似的结果:

Prompt>echo $(((1000000001+1000000002+1000000003+1000000004+1000000005)%2147483647))
705032721
Prompt>echo $(((1000000001+1000000002+1000000003+1000000004+1000000005)%4294967295))
705032720

这一切意味着什么?

几乎C中的每个基本类型都有其局限性,整数(uintint(仅限于UINT_MAXINT_MAX。这些值由您的系统决定,但它们大多是值,如2147483647或4294967295。

您似乎使用的是大于这些值的数字,因此您需要使用具有更大限制的整数类型,但要注意这些类型也有限制(这也由您的系统决定(。如果您有兴趣使用超过系统限制的值,您可能需要使用整数的动态数组,其中数组的元素是数字,数字是由数字创建的。

您可能需要一些用于任意精度算术的库,也称为bignums,以避免一些整数溢出。在大多数系统上,int有32位,但有关详细信息,请参阅C20标准草案和本C参考文件。当然,请阅读C编译器的文档(例如GCC(。

例如,我建议使用GMPlib。特别是因为:

  • bignum算法需要复杂的算法,如果你想提高的效率

  • GMPlib利用了专门的硬件机器指令,并使用汇编程序编写了低级代码。

当然要注意GMPlib确实有局限性(特别是,它对内存不足的情况不友好(。GMPlib是开源的,所以你可以下载和研究它的源代码,甚至改进它

在一些机器上使用一些最新的编译器(如2020年底的GCC 10(,您可以使用128位整数(但随后您的程序可能会在它们上进行整数溢出实验,产生巨大的数字(。

确保启用所有警告和调试信息,例如使用gcc -Wall -Wextra -O -g编译

您还可以考虑使用带有bignum的编程语言,例如Common Lisp(例如使用SBCL(。

当然,你的电脑内存仍然有限,这是一个巨大的限制。另请参见此。

最新更新