This question already has answers here:
Sum of positive values in an array gives negative result in a c program
(4 answers)
Closed 4 years ago.
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.
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.
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.
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);
}
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.
Related
My Code is taking too much time and possibly giving a wrong answer after a certain limit . What i have observed is the code slows down after I give N>50000 .
int solve(int N)
{
long long int temp=0;
long long int sum=0;
const long long int mod=1000000007;
for(int i=1;i<=N;i++)
{
for(int j=i;j<=N;j++)
{
temp=0;
if((i&j)==0)
{
temp=i*j;
sum=sum+temp;
}
}
}
return sum%mod;
}
I am trying to achieve results for N>=1 to N<=200000.
Can it be that the variable sum is going beyond the scope of long long int after a certain limit?
temp=i*j;
Since i,j are both of type int, this multiplication is done as int (likely signed 32-bit), and if it overflows the largest int (2**31-1) then you have undefined behavior and will certainly not get the right answer. A little quick math shows this will happen as soon as N exceeds 46340 which is around the 50000 you mention. The fact that the result is assigned to a variable of type long long int doesn't change the way the sub-expression i*j is evaluated, so it doesn't solve your overflow problem.
To get the multiplication to be done as long long int (at least 64 bits), you have to cast one or both of the operands:
temp = ((long long int)i) * j;
(Cast has higher precedence than multiplication so you can actually write temp = (long long int)i * j; but I tend to find this is less clear to read.)
This would explain the "possibly wrong answer" but has nothing to do with the slowness, which as others mentioned comes inherently from your quadratic algorithm. However even with N=200000 it finishes in about 8 seconds on my computer. Make sure you are using a good-quality optimizing compiler and that you have optimizations turned on.
Your question (2) about overflowing sum is not an issue though. Each of the summands i*j is at most N**2, and there are at most N such summands, so the maximum value of sum is at most N**3. You can verify that 200000**3 is still much smaller than 2**63.
So I have some code to get some large numbers, and I am storing them in long, but the output is still not correct because I get negative numbers.
Here is my code:
int user_want =0;
long answer=1;
int loop = 0;
printf("What is required?");
scanf("%d", &user_want);
for(loop=1;loop<=user_want; loop++){
answer = answer*loop
printf("%ld\n", answer)
}
I get this output:
Pls help!
On most platforms long is the same as int. You need to use long long which uses more bytes (again, on most platforms :-) ). You can print out sizeof(int), sizeof(long), etc. to see how many bytes they use on your platform.
BTW, the numbers you get is simply the result of overflow in the computation.
I have created a myfun.h header file with two functions in it. A factorial function and amstrong function and a myfun.c file
Here is myfun.h program
void factorial(int n,int *fact)
{
int i;
*fact=1;
for(i=1;i<=n;i++)
*fact=*fact*i;
}
amstrong(int n)
{
int sum=0,num,rem,cube;
num=n;
while(num>0)
{
rem=num%10;
cube=rem*rem*rem;
num=num/10;
sum=sum+cube;
}
if(sum==n)
return(1);
else
return(0);
}
Here is the myfun.c program
#include<stdio.h>
#include "myfun.h"
int main()
{
int num,rev,f,code;
printf("Enter number :");
scanf("%d",&num);
code=amstrong(num);
if(code==1)
printf("\nNumber is amstrong\n");
else
printf("Number is not amstrong\n");
factorial(num,&f);
printf("Factorial of %d is %d ",num,f);
getch();
}
In this the amstrong function is working fine.But the factorial function is giving output 0. I haven't tried it without removing pointer variable. But if i want to run it with pointer variable then what changes i need to do?
The output of program is
Enter number: 153
Number is amstrong
Factorial of 153 is 0
153! = 2.01 E+269.
In case unsigned long long is 64 bits, it can hold a maximum value of 2^64 = 18.45 E+19.
You will need to use some form of "big int" library to calculate huge numbers like these.
This is happening because there is a every data type can hold upto a certain number. The reason that you are getting wrong answer is because the fact of 153 would be bigger then what an int variable can hold. It should work fine for smaller values.
Edit
To store larger numbers you can use long long int data type.
The minimum data type ranges you can use are:
short int and int: -32,767 to 32,767
unsigned short int and unsigned int: 0 to 65,535
long int: -2,147,483,647 to 2,147,483,647
unsigned long int: 0 to 4,294,967,295
int alone cannot store the value given by fact (153). Use smaller values for your case, otherwise change the type: use a long long int instead.
sizeof(long double) = 12bytes on a machine running 32-bit linux. The output can be printed by using %LE in printf. Output will be in exponential form.
EDIT
factorial(20) : 2432902008176640000 when using long long int
This is maximum you can get with long long int type of variable.
For greater ranges use long double.
I wrote some code to determine the nth Fibonacci number using the nice blog post given in the accepted answer to this question: Finding out nth fibonacci number for very large 'n'. I am doing this as a way of practising a more difficult recursion problem given on projecteuler but that is not really relevant. The method relies on changing the problem to a small linear algebra problem of the form
Fn = T^n F1
where F1 = (1 1)^t and Fn contains the nth and (n-1)th Fibonacci number. The term T^n can then be determined in O(log n) time. I implemented this succesfully and it seems to work fine. When I perform the matrix exponentiation I use %10000 so I get the last 4 digits only, which seems to work (I checked against some large Fibonacci numbers). However, I wanted to try to get more last digits by increasing the number 10000. This doesn't seem to work however. I no longer get the correct answer. Here is my code
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
const unsigned long M = 10000;
unsigned long int * matProd(unsigned long int * A, unsigned long int * B){
unsigned long int * C;
C = malloc(4*sizeof(unsigned long int));
C[0] = ((A[0]*B[0]%M) + (A[1]*B[2]%M)) % M;
C[1] = ((A[0]*B[1]%M) + (A[1]*B[3]%M)) % M;
C[2] = ((A[2]*B[0]%M) + (A[3]*B[2]%M)) % M;
C[3] = ((A[2]*B[1]%M) + (A[3]*B[3]%M)) % M;
return C;
}
unsigned long int * matExp(unsigned long int *A, unsigned long int n){
if (n==1){
return A;
}
if (n%2==0){
return matExp(matProd(A,A),n/2);
}
return matProd(A,matExp(A,n-1));
}
unsigned long int findFib(unsigned long int n){
unsigned long int A[4] = {0, 1, 1, 1};
unsigned long int * C;
C = malloc(4*sizeof(unsigned long int));
C = matExp(A,n-2);
return (C[2]+C[3]);
}
main(){
unsigned long int n = 300;
printf("%ld\n",findFib(n));
}
There are probably several issues there with regards to proper coding conventions and things that can be improved. I thought changing to long int might solve the problem but this does not seem to do the trick. So basically the problem is that increasing M to for instance 1000000 does not give me more digits but instead gives me nonsense. What mistake am I making?
P.S. sorry for the poor math formatting, I am used to math.stackexchange.
The issue is probably that you are running on a system where long is 32-bits in size, as I believe is the case for Windows. You can check this by compiling and running printf("%d\n", sizeof(long)) which should output 4.
Since with M=1000000=10^6, the product of two numbers smaller than M can go up to 10^12, you get overflow issues when you are computing your matrix entries since unsigned long can hold up to at most 2^32-1 or roughly 4 * 10^9.
To fix this simply using unsigned long long as your type instead of unsigned long. Or better yet, uint64_t, which is guaranteed to be 64-bits in all platforms (and which will require #include <stdint.h>). This should make your code work for M up to sqrt(2^64)~10^9. If you need bigger than that you'll need to use a big integer library.
If the program works for M == 10000 but fails for M == 1000000 (or even for M == 100000) then that probably means that your C implementation's unsigned long int type is 32 bits wide.
If your matrix elements are drawn exclusively from Z10000, then they require at most 14 significant binary digits. The products you compute in your matrix multiplication function, before reducing modulo M, may therefore require up to 28 binary digits. If you increase M even to 100000, however, then the matrix elements require up to 17 binary digits, and the intermediate products require up to 34. The reduction modulo M is too late to prevent that overflowing a 32-bit integer and therefore giving you garbage results.
You could consider declaring the element type as uint64_t instead. If it's an overflow problem then that should give you enough extra digits to handle M == 1000000.
I wrote this simple code to generate 4th power of all positive integers up to 1005. It works fine only up to integer 215. After that it gives erroneous readings. why so?
# include<stdio.h>
int main(void)
{
int i;
unsigned long long int j;
for (i = 1; i <= 1005; i++){
j = i*i*i*i;
printf("%i.........%llu\n",i,j);
}
return 0;
}
You can fix it by making this small change.
unsigned long long i;
The problem is that in the line j = i*i*i*i;, the right hand side is being calculated as an int before it is being assigned to j. Because of this if i^4 exceeds integer limits, it will basically start to go first negative and start cycling around when higher bits get clipped. When the negative number is assigned to j, since j is unsigned, -i becomes max - i, which is where the huge numbers come from. You will also need to change the printf format specifier from %i to %llu for i.
You can also fix this by doing the below
j = (unsigned long long)i*i*i*i;
This basically forces a cast up to the type of j before performing the multiplication.
Sanity check - 215 ^4 = 2136750625 which is very close to the upper limit of signed int of 2,147,483,647.
i*i produces an int. And so do i*i*i and i*i*i*i. 215 is the greatest positive integer whose 4th power fits into a 32-bit int.
Beyond that the result is typically truncated (typically because strictly speaking you are having a case of undefined behavior; signed integer overflows result in UB per the C standard).
You may want to cast i to unsigned long long or define it as unsigned long long, so the multiplications are 64-bit:
j = (unsigned long long)i*i*i*i;