Reputation: 1719
I read that *
(multiplication) has has higher presedence than /
(division). Thus if there is an equation with both *
and /
, then *
must take place first.
But I've seen a program that output something strange
#include<stdio.h>
#define SQUARE(x) x*x
int main()
{
float s=10, u=30, t=2, a;
a = 2*(s-u*t)/SQUARE(t);
printf("Result = %f", a);
return 0;
}
When running this, I thought that the output would be -25, but in fact it was -100.
When I looked for the explanation it was
Step 2: a = 2*(s-u*t)/SQUARE(t); becomes,
// Here SQUARE(t) is replaced by macro to t*t
=> a = 2 * (10 - 30 * 2) / t * t;
=> a = 2 * (10 - 30 * 2) / 2 * 2;
=> a = 2 * (10 - 60) / 2 * 2;
=> a = 2 * (-50) / 2 * 2 ;
/*till here it's OK*/
/*why it divided -50 by 2 before multiplying 2*2 and -50*2 */
=> a = 2 * (-25) * 2 ;
=> a = (-50) * 2 ;
=> a = -100;
Can any one explain please?
Upvotes: 1
Views: 251
Reputation: 726499
It does not do what you think it does: after the step marked /*till here it's OK*/
, the operations proceed in their regular order for multiplicative operators, i.e. left to right:
=> a = 2 * (-50) / 2 * 2 ;
/*till here it's OK*/
=> a = -100 / 2 * 2 ; // Division
=> a = -50 * 2 ; // Multiplication
=> a = -100 ; // Done
Your code is a perfect example of why one needs to be very careful with macros: parenthesizing macro's parameters would fix this particular problem, but some problems are simply non-fixable. For example, your macro would remain unsuitable for expressions with side effects:
#define SQUARE(X) ((x)*(x))
// Still not good:
int a = 2;
// Undefined behavior, because ((a++)*(a++)) uses expressions with side effects without a sequence point
int b = SQUARE(a++);
For this reason, you would be better off making SQUARE
a function.
Upvotes: 2
Reputation: 16184
Division and muliplication have the same precedence, and are thus evaluated from left to right. http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
Upvotes: 3
Reputation: 98348
Parenthesis paranoia! Your macro should be:
#define SQUARE(X) ((x)*(x))
Or else precedence rules and macro expansion will do weird things. Your macro:
100 / SQUARE(2)
will expand to:
100 / 2*2
and that is read as:
(100/2) * 2
which is 100, not 25.
Other anomaly, not in your code is if you try to square an expression:
SQUARE(2+2)
will expand to
2+2*2+2
which is 8
, not the expected 16
.
Conclusion: in macros write a lot of parentheses. Everywhere.
Upvotes: 5