2

I have written the following c code to find the sum of first 49 numbers of a given array, but the sum is coming out to be negative.

#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);
}

i don't know why it is coming so?please help.

Coderandhacker
  • 135
  • 1
  • 11

4 Answers4

4

I didn't actually add them up, but just looking at them, I'd say its a pretty safe guess that you are running into an integer overflow error.

A long int has a maximum size of about 2 billion (2^31). If you add more than that, it'll look back around and go to -2^31.

You'll need to use a data type that can hold more than that if you want to sum up those numbers. Probably a long long int should work. If you're sure it'll always be positive, even better to use an unsigned long long int.

Rivasa
  • 6,510
  • 3
  • 35
  • 64
samanime
  • 25,408
  • 15
  • 90
  • 139
  • It would be good to elaborate on that "error" part: allowing signed integer over/underflow to occur is a programmer error because it invokes undefined behaviour, although the language is not required to emit a diagnostic at compile- or run-time. (Maybe I should just add my own answer instead of bugging everyone else) – underscore_d Apr 13 '18 at 15:24
  • A `long int` is at least 32 bits, but there's nothing in the C standard guaranteeing it to not be, say, 64 bits. – Christian Gibbons Apr 13 '18 at 16:26
  • @underscore_d Yes, it's not a thrown exception. It's a logic error. – samanime Apr 13 '18 at 17:02
4

Using long long instead of long, the program works:

Ouput: 56074206897

Reason
Range of long: -2^31+1 to +2^31-1
Range of long long: -2^63+1 to +2^63-1

As you can see 2^31-1 = 2147483647 < 56074206897;
but 2^63-1 = 9,223,372,036,854,775,807 > 56074206897

This leads to overflow. According to the C standard, the result of signed integer overflow is undefined behavior. What that means is that if this condition ever happens at runtime, the compiler is allowed to make your code do anything. Your program could crash, or produce the wrong answer, or have unpredictable effects on other parts of your code, or it might silently do what you intended.

In your case it is overflowing the maximum value of long int on your system. Because long int is signed, when the most significant bit gets set, it becomes a negative number.

Abhishek Keshri
  • 3,074
  • 14
  • 31
2

As Vlad from Moscow said this is a overflow issue, which made an undefined behavior. In you system (long int sum) sum does not have capacity to hold the total value. Not sure but you can use long long int sum =0;(after C99). If it still cannot work properly, search for "BigInteger" implement.

con ko
  • 1,368
  • 5
  • 18
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
  • 1
    As well as being vague and untested, this doesn't explain why it wraps to a negative value, instead of some other behaviour that might be expected (e.g. clamping at the maximum) - or what the danger of that is, i.e. that signed integer over/underflow is undefined behaviour by the Standard. – underscore_d Apr 13 '18 at 15:19
2

As long int has maximum range upto 2,147,483,647, and the value of sum is more than the range.So, it is coming as negative value. You can use the following code...

#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);
}
  • 1
    This doesn't explain why it wraps to a negative value, instead of some other behaviour that might be expected (e.g. clamping at the maximum) - or what the danger of that is, i.e. that signed integer over/underflow is undefined behaviour by the Standard. – underscore_d Apr 13 '18 at 15:18