Multiplication and division: weird output in c

余生长醉 提交于 2020-01-22 01:31:33

问题


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?


回答1:


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.




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/21060979/multiplication-and-division-weird-output-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!