'Two different answers for same expression in C

I have an expression which does the same calculation. When I try to do the whole calculation in a single expression and store it in variable "a", the expression calculates the answer as 0. When I divide the equations in two different parts and then calculate it, it gives the answer -0.332087. Obviously, -0.332087 is the correct answer. Can anybody explain why is this program misbehaving like this?

#include<stdio.h>

void main(){
    double a, b, c;
    int n=0, sumY=0, sumX=0, sumX2=0, sumY2=0, sumXY=0;
    n = 85;
    sumX = 4276;
    sumY = 15907;
    sumX2 = 288130;
    sumY2 = 3379721;
    sumXY = 775966;
    a = ((n*sumXY) - (sumX*sumY)) / ((n*sumX2)-(sumX*sumX));
    b = ((n*sumXY) - (sumX*sumY));
    c = ((n*sumX2) - (sumX*sumX));
    printf("%lf\n", a);
    printf("%lf\n", b/c);
}

Output:
0.000000
-0.332097


Solution 1:[1]

In your program

a = ((n*sumXY) - (sumX*sumY)) / ((n*sumX2)-(sumX*sumX));

all the variables in the right hand side are of type int, so it will produce a result of type int. The true answer -0.332097 is not a int value, so it will be converted to a valid int value, namely 0. And this 0 is assigned to variable a.

But when you do

b = ((n*sumXY) - (sumX*sumY));
c = ((n*sumX2) - (sumX*sumX));
printf("%lf\n", b/c);

The variable b and c are of type double, so the expression b/c produce a double typed value and the true answer -0.332097 is a valid double value. Thus this part of your code give a right result.

Solution 2:[2]

In first equation i.e. a = ((n*sumXY) - (sumX*sumY)) / ((n*sumX2)-(sumX*sumX)) both numerator and denominator will give integer results and the value stored in a will also be integer as integer/integer is integer. In second and third expression as you are solving them individually both b and c will be stored in double and double/double will result in a double i.e. a decimal value.

This problem can be solved by using type casting - or better still using float for the variables.

Solution 3:[3]

Add double before your calculation, so after you do your integer calculation in "a", it will convert it to double.

a = (double)((n*sumXY) - (sumX*sumY)) / ((n*sumX2)-(sumX*sumX));

Solution 4:[4]

First of all (INTEGER)/(INTEGER) is always an INTEGER. So, you can typecast it like a = (double)(((n*sumXY) - (sumX*sumY)) / ((n*sumX2)-(sumX*sumX)));

OR

We know that any number (n ? ?), multiplied by 1.0 always gives the same number (n). So, your code shall be like:

a = ((n*sumXY*1.0L) - (sumX*sumY)) / ((n*sumX2)-(sumX*sumX));

Multiplying by 1.0L or 1.0f converts the whole arithmetic operation to long double data type. Now you can print the number (-0.332097) to stdout.

Non-standard Code

Your code is:
void main()
{
     //// YOUR CODE
}

Which is non-standard C. Instead your code should be like:

int main(int argc, char **argv)
{
     //// YOUR CODE
     return 0;
}

Solution 5:[5]

Change all your INTEGERS to DOUBLES. That should solve the problem

Solution 6:[6]

The type of 1st expression is int whereas in 2nd expression it is double.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Foolhardy Hardy
Solution 2 Andrew
Solution 3 Hardwarics
Solution 4
Solution 5 Bugz
Solution 6 Vishal