C 为什么总和的值是负值?

C 为什么总和的值是负值?,c,arrays,C,Arrays,我编写了下面的c代码来计算给定数组的前49个数字的和,但结果是负数 #include<stdio.h> int main() { int i; long int sum=0; long int a[50]={846930887,1681692778,1714636916, 1957747794, 424238336, 719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028, 78

我编写了下面的c代码来计算给定数组的前49个数字的和,但结果是负数

#include<stdio.h>
int main()
{
    int i;
    long int sum=0;
    long int a[50]={846930887,1681692778,1714636916, 1957747794, 424238336, 719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028, 783368691, 1102520060, 2044897764, 1967513927, 1365180541, 1540383427, 304089173, 1303455737, 35005212, 521595369, 294702568, 1726956430, 336465783, 861021531, 278722863, 233665124, 2145174068, 468703136, 1101513930, 1801979803, 1315634023, 635723059, 1369133070, 1125898168, 1059961394, 2089018457, 628175012, 1656478043, 1131176230, 1653377374, 859484422, 1914544920, 608413785, 756898538, 1734575199, 1973594325, 149798316, 2038664371, 1129566414};
    for(i=0;i<49;i++)
    {
        sum=sum+a[i];
        printf("sum is : %ld\n",sum);
    }
    printf("\nthe total sum is %ld",sum);
}
#包括
int main()
{
int i;
长整数和=0;
长整数a[50]={846930887,1681692778,1714636916, 1957747794, 424238336, 719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028, 783368691, 1102520060, 2044897764, 1967513927, 1365180541, 1540383427, 304089173, 1303455737, 35005212, 521595369, 294702568, 1726956430, 336465783, 861021531, 278722863, 233665124, 2145174068, 468703136, 1101513930, 1801979803, 1315634023, 635723059, 1369133070, 1125898168, 1059961394, 2089018457, 628175012, 1656478043, 1131176230, 1653377374, 859484422, 1914544920, 608413785, 756898538, 1734575199, 1973594325, 149798316, 2038664371, 1129566414};

对于(i=0;i我实际上并没有将它们相加,但只要看看它们,我就会说,很有把握的猜测是您遇到了整数溢出错误

一个
long int
的最大值约为20亿(2^31)。如果您添加的值超过这个值,它将返回到-2^31


如果你想对这些数字进行求和,你需要使用一个能容纳更多数据的数据类型。可能
长整型
可以工作。如果你确定它总是正的,最好使用
无符号长整型

,正如莫斯科的弗拉德所说,这是一个溢出问题,导致了一种未定义的行为。在你身上系统(
long int sum
sum
没有保存总值的能力。不确定,但您可以使用
long long int sum=0;
(在C99之后)。如果它仍然无法正常工作,请搜索“biginger”实现。

使用
long long
而不是
long
,程序工作:

输出:56074206897

原因
长期范围:-2^31+1至+2^31-1
长-长范围:-2^63+1至+2^63-1

如您所见,2^31-1=2147483647< 56074206897;
但2^63-1=9223372036854775807>56074206897

这会导致溢出。根据C标准,有符号整数溢出的结果是未定义的行为。这意味着,如果在运行时发生这种情况,编译器可以让您的代码执行任何操作。您的程序可能会崩溃,或产生错误的答案,或对其他程序产生不可预测的影响代码的一部分,或者它可能会默默地执行您想要的操作


在您的情况下,它溢出了系统上的最大值
long int
。因为
long int
是有符号的,当设置最高有效位时,它会变成一个负数。

因为long int的最大范围高达2147483647,并且sum的值大于该范围。因此,它将作为负值出现。您可以请输入以下代码

#include<stdio.h>
int main()
{
    int i;
    long long int sum=0;    //Taking long long int instead of long int
    int a[50]={846930887,1681692778,1714636916, 1957747794, 424238336, 
    719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028, 
    783368691, 1102520060, 2044897764, 1967513927, 1365180541, 1540383427, 
    304089173, 1303455737, 35005212, 521595369, 294702568, 1726956430, 
    336465783, 861021531, 278722863, 233665124, 2145174068, 468703136, 
    1101513930, 1801979803, 1315634023, 635723059, 1369133070, 1125898168, 
    1059961394, 2089018457, 628175012, 1656478043, 1131176230, 1653377374, 
    859484422, 1914544920, 608413785, 756898538, 1734575199, 1973594325, 
    149798316, 2038664371, 1129566414};
    for(i=0;i<49;i++)
    {
        sum=sum+a[i];
        printf("sum is : %lld\n",sum);
    }
    printf("\nTotal sum is %lld",sum);
}
#包括
int main()
{
int i;
long long int sum=0;//取long long int而不是long int
INTA[50]={84693088716816927781714636916195777794424238336,
719885387, 1649760493, 596516650, 1189641422, 1025202363, 1350490028, 
783368691, 1102520060, 2044897764, 1967513927, 1365180541, 1540383427, 
304089173, 1303455737, 35005212, 521595369, 294702568, 1726956430, 
336465783, 861021531, 278722863, 233665124, 2145174068, 468703136, 
1101513930, 1801979803, 1315634023, 635723059, 1369133070, 1125898168, 
1059961394, 2089018457, 628175012, 1656478043, 1131176230, 1653377374, 
859484422, 1914544920, 608413785, 756898538, 1734575199, 1973594325, 
149798316, 2038664371, 1129566414};

对于(i=0;iDue to overflow?在我的编译器上运行良好系统上的
long int
有多大?将
long int
更改为
unsigned long long int
,并将
%ld
更改为
%llu
,再试一次。这并没有解释为什么它会换行为负值,而不是预期的其他行为(例如,最大限位)-或其危险性是什么,即有符号整数溢出/下溢是标准中未定义的行为。除了模糊和未经测试外,这并不能解释为什么它会被包装为负值,而不是预期的其他行为(例如,最大限位)-或其危险是什么,即有符号整数溢出/下溢是标准中未定义的行为。最好详细说明该“错误”部分:允许出现有符号整数溢出/下溢是一个程序员错误,因为它调用了未定义的行为,尽管不需要该语言在编译或运行时发出诊断(也许我应该添加我自己的答案,而不是对其他人进行窃听)一个
long int
至少是32位,但是在C标准中没有任何东西保证它不是,比如说,64位。@下划线\d是的,它不是抛出的异常。它是一个逻辑错误。