This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 1 year ago.
I'm a beginner in programming and I have a question. Mainly, what is the difference in defining PI exactly as I state below;
#define PI (4.*atan(1))
#define PIa 4.*atan(1)
#define PIb 4*atan(1)
I have printed this code:
printf( "%lf\n", 3 / PI );
printf( "%lf\n", 3 / PIa );
printf( "%lf\n", 3 / PIb );
The results are:
0.954930
0.589049
0.000000
According to my calculator the first one is correct, and the rest should also be.
Why aren't they?
The macro is text substitution thus:
3 / PIa
is parsed as:
3 / 4.*atan(1) = (3/4.) * atan(1)
This is different from the first case where 3 / PI is expanded as:
3 / (4.*atan(1))
The similar case is for the third example:
3 / 4*atan(1) = (3/4) * atan(1)
The expression 3/4 is integer division, which result is 0.
Generally, it is strongly advised to put parentheses around the whole macro and all parameters it takes like in the following example:
#define ADD(a,b) ((a) + (b))
Related
The code below does not give the correct output.
#include <stdio.h>
#define PI 22/7
#define AREA(r) PI * r * r
int main() {
printf("Pi: %d\n", PI);
printf("Area: %d\n", AREA(8));
return 0;
}
Whereas the code below gives the correct (nearest) output.
#include <stdio.h>
#define PI 22/7
#define AREA(r) r * r * PI
int main() {
printf("Pi: %d\n", PI);
printf("Area: %d\n", AREA(8));
return 0;
}
How exactly do these code differ?
Why is it so? I am not able to understand the difference between how both the above codes would give different answers.
The problem is your PI macro:
#define PI 22/7
There are two problems with this: (1) It's not wrapped in parentheses, to guard it against parts of it binding more tightly to other parts of the expression in which it's expanded, and (2) It's doing integer division.
If you have 22/7 by itself, it's just 3. Presumably that's not what you want. But the AREA macro, which also has problems, looks like this:
#define AREA(r) r * r * PI
With PI expanded, this is equivalent to:
#define AREA(r) r * r * 22/7
Assuming r is a simple variable or constant, this is equivalent to:
#define AREA(r) (r * r * 22) / 7
If r is an integer, it's still doing integer division, but it's only truncating at the end, so the result will be more accurate.
Note that AREA has two problems of its own: (1) It's not wrapping its argument, r, in parentheses, and (2) It's not wrapping the expression as a whole in parentheses.
For problem (1), imagine passing something like 2+3 as r. Since multiplication associates more tightly than addition, this clearly won't do what you want.
If you want an accurate result, you would normally use an accurate floating-point value for pi, rather than the extremely inaccurate approximation 22/7. But if you do want to use 22/7, you should still use a floating point value for it:
#define PI (22.0/7.0)
Then you can fix AREA:
#define AREA(r) (PI * (r) * (r))
This will properly protect the arguments and final results from reassociating after expansion, but note that the result will have type double. Also note that its argument, r, is evaluated twice.
But a better approximation to pi is preferable. On Linux, math.h exports M_PI, which is far more accurate.
Try expanding the macro. The first one is 22 / 7 * 8 * 8. All values are integers, so you get rounding errors and the calculation is basically 3 * 8 * 8 = 192.
The second expression is 8 * 8 * 22 / 7. So the calculation is 1408 / 7 = 201.
Multiplication and division is done from left to right.
So, AREA(8) in the first example expands to
22/7 * 8 * 8 which is evaluated like so:
(((22/7) * 8) * 8), i.e 3 * 8 * 8 = 192.
The other variant gives:
(((8*8)*22)/7) = (64 * 22)/7 = 1408/7 = 201.
If you want better precision, use floating point, i.e.
#define PI (22.0/7.0)
or, why not use a better approximation of pi:
#define PI (3.141593)
But then you should use %f in printf. (as commented by Jabberwocky)
This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 3 years ago.
I find no difference between these two macros except the parentheses surrounding the macro in the first one.
Is it a matter of readability or is it a way to deal with the priority of operators?
#define TAM_ARRAY(a) (sizeof(a)/sizeof(*a))
#define TAM_ARRAY2(a) sizeof(a)/sizeof(*a)
Yes, there is a difference. The parentheses are needed so that the result of the macro is evaluated as a single expression, rather than being mixed with the surrounding context where the macro is used.
The output of this program:
#include <stdio.h>
#define TAM_ARRAY(a) (sizeof(a)/sizeof(*a))
#define TAM_ARRAY2(a) sizeof(a)/sizeof(*a)
int main(void)
{
int x[4];
printf("%zu\n", 13 % TAM_ARRAY (x));
printf("%zu\n", 13 % TAM_ARRAY2(x));
}
is, in a C implementation where int is four bytes:
1
3
because:
13 % TAM_ARRAY (x) is replaced by 13 % (sizeof(x)/sizeof(*x)), which groups to 13 % (sizeof(x) / sizeof(*x)), which evaluates to 13 % (16 / 4), then 13 % 4, then 1.
13 % TAM_ARRAY2(x) is replaced by 13 % sizeof(x)/sizeof(*x), which groups to (13 % sizeof(x)) / sizeof(*x), which evaluates to (13 % 16) / 4, then 13 / 4, then 3.
Along these lines, TAM_ARRAY would be better to include parentheses around the second instance of a as well:
#define TAM_ARRAY(a) (sizeof(a)/sizeof(*(a)))
Macros are replaced textually in an early phase of code translation. Unless side effects are specifically expected, it is very important to fully parenthesize macro arguments in the macro expansion and the macro expansion itself if it is an expression.
In the case posted, you are unlikely to have a problem because few operators have higher precedence and they would probably not be used around the macro expansion, but here is a pathological example:
TAM_ARRAY(a)["abcd"] expands to (sizeof(a)/sizeof(*a))["abcd"] whereas
TAM_ARRAY2(a)["abcd"] expands to sizeof(a)/sizeof(*a)["abcd"] which is equivalent to sizeof(a) / (sizeof(*a)["abcd"]).
Note however that an operator with the same precedence placed before the macro expansion such as % would definitely cause problems as explained in Eric Postpischil's answer.
Note also that a should be parenthesized too:
#define TAM_ARRAY(a) (sizeof(a) / sizeof(*(a)))
The way macros work is that the code is "swapped out" when compiling.
So something like
#define ADD(i, j) i + j
int k = ADD(1, 2) * 3
would be seen as: int k = 1 + (2 * 3)
Whereas,
#define ADD(i, j) (i + j)
int k = ADD(1, 2) * 3
would be seen as: int k = (1 + 2) * 3
So, there are two macros likely because of operator priority.
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 4 years ago.
I am not able to understand this code
#define sqt(x) x*x
int main(){
print("%d",sqt(3+1));
}
Manually I am getting the output of 10. But when write the code and compile it I am getting the answer as 7. Please explain this.
Remember, since you're using a macro, 3 + 1 is not evaluated before sqt is called. x becomes 3 + 1 (not 4), then order of operation causes an unexpected answer to be produced since addition happens after multiplication.
Or in other words:
sqt(3 + 1)
expands to:
3 + 1 * 3 + 1
Then, when you evaluate this like you would any other equation:
3 + 1 * 3 + 1 // Multiplication happens first
= 3 + 3 + 1
= 7
This is a good example of why you shouldn't use macros unless they're strictly necessary, or you've made proper care to ensure that things like order of operation mistakes don't happen. As #Barmar points out this particular case can be remedied by having the macro expand to include explicit parenthesis:
#define sqt(x) ((x)*(x))
Which would cause the evaluation to differ and give a proper answer:
(3 + 1) * (3 + 1)
4 * 4
16
This question already has answers here:
Why I am getting zero in float expressions like 1/2? [duplicate]
(2 answers)
Closed 5 years ago.
I have the following code in a header file for an AVR32 program I'm writing:
#define PULSE_FREQ 150
#define TC_FREQ (60000000 / 8)
#define PULSE_PER (1 / PULSE_FREQ)
#define TC_PER (1 / TC_FREQ)
#define TTC ((PULSE_PER / TC_PER) - 1)
The goal is to be able to give a frequency and calculate the constant timer count value given by this formula:
Target Count = ((1 / Target Frequency) / (1 / Timer Frequency)) - 1
For example, for a timer frequency of 150Hz, a timer count value of 49999 is required. When manually entering that value for the timer, it works and gives a frequency of 150Hz. However, when using the code above, I get a frequency of 57Hz.
I'm also getting warnings about a division by zero, could the numbers in the constants be so small that they're getting chopped off to zero?
Would it be better to go about this at runtime instead of with #define macros?
The integer division is probably returning a number less than 1 at some point, and it's being truncated to 0.
Try forcing floating-point division by making one of the constants a double:
// The .0 should "infect" the other numbers
#define PULSE_FREQ 150.0
#define TC_FREQ (60000000 / 8)
#define PULSE_PER (1 / PULSE_FREQ)
#define TC_PER (1 / TC_FREQ)
#define TTC ((PULSE_PER / TC_PER) - 1)
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 6 years ago.
I defined a function using #define, but when I print out a simple result of an operation it gives me an unexpected result. Here is the code:
#include <stdio.h>
#define CUBE(x) (x * x * x)
int main() {
int m, n = 3;
m = CUBE(n + 1);
printf("%d %d", m, n--);
return 0;
}
The result printed is 10 and 3 and I can't understand why. Since it multiplies n by itself 3 times, and then adds 1, shouldn't the result be 28 and 3?
You don't #define functions, you #define macros, and those are quite different from functions.
They aren't called. They are expanded into the source code directly by the preprocessor, before the code is compiled by the compiler.
They have pitfalls that one must be aware of. To name one, if you pass an expression with side effects to a macro the uses its parameter more than once, the side effects will occur more than once, and you may get wrong results.
The substation is plain token substitution, so
CUBE(n + 1)
will be expand to this:
(n + 1 * n + 1 * n + 1)
#define CUBE(x) ((x) * (x) * (x))
should give you the expected result.
In your, on preprocessing, x in CUBE(x) is replaced by 3+1 which gives you
(3+1 * 3+1 * 3+1) // this happens during pre-processing, not in run time
as macro is plain-text replacement.
which will be grouped like
(3+(1 * 3)+(1 * 3)+1)
giving you 10. For more complex cases, I suggest writing a function.
As the previous answer already suggest, you are missing a pair of brackets,
because the preprocessor basically does find and replace. So your version result in
m = n + 1 * n + 1 * n + 1
which evaluates to the result, you observed.
With
#define CUBE(x) ((x) * (x) * (x))
you will get the correct calculation of
m = (n + 1) * (n + 1) * (n + 1)