coderzz027
coderzz027

Reputation: 349

Error using macros

I have this code where I am processing the data. It is a code Chef question. I take a series of inputs from the user and process them to find the maximum difference between 2 numbers. But when I use macros to get maximum difference it gives me a wrong answer, where as when I use the function (which I have currently commented) gives the right answer. Here is the code.

#include <stdio.h>
#define mod(a,b)a>b?a-b:b-a
/*int mod(int a, int b)
{
    if(a>b)
        return a-b;
    else
        return b-a;
}*/
int main()
{
    int p1,o1=0;//player1
    int p2,o2=0;//player2
    int margin=0;//win margin
    int rounds;//number of rounds
    scanf("%d",&rounds);
    while(rounds--)
   {
        scanf("%d %d",&p1,&p2);
        o2+=p2;o1+=p1;
        if(mod(o1,o2)>mod(margin,0))
            margin=o1-o2;
    }
    if(margin<0)
        printf("%d %d\n",2,margin*-1);
    else
        printf("%d %d\n",1,margin);
    return 0;
}

The sample input that I enter is:

5
140 82
89 134
90 110
112 106
88 90

1 The expected answer of this input is:: 1 58

whereas when I use macro to do the computations it gives an output that looks like this::

2 3

Why is the macro giving wrong answer. Please do rep guys.. Thanks in advance..

Upvotes: 4

Views: 79

Answers (3)

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16112

mod(o1,o2)>mod(margin,0)

becomes

o1>o2?o1-o2:o2-o1>margin>0?margin-0:0-margin

which gets parsed as

o1>o2 ? o1-o2 : ( ((o2-o1)>margin) > 0 ) ? margin-0 : 0-margin

The ternary operator has very low priority, just above assignment. Everything else on the right side gets evaluated first, and only then the ternary. This includes the greater than between the two mods. This is only possible because C treats boolean expressions as arithmetic values and happily computes on with them -- any decent language would balk here. The result of the first comparison is 0 or 1 and used in the next one, comparing it against 0. How to fix this by bracketing properly or, better, using functions (modern compilers inline them later anyway!) has been described by the others.

Upvotes: 2

user3971717
user3971717

Reputation: 91

Macros perform textual substitutions. As a result, when they get "pasted" into code, unexpected side effects can occur. You want to wrap your arguments in parentheses to get the correct result.

i.e:

#define mod(a,b) ( ( a ) > ( b ) ? ( a ) - ( b ) : ( b ) - ( a ) )

This ensures that whatever is substituted for a and b are correctly "grouped".

Upvotes: 5

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

The correct macro will look like

#define mod(a,b) ( ( a ) > ( b ) ? ( a ) - ( b ) : ( b ) - ( a ) )

Upvotes: 6

Related Questions