C symbolic constant wrong value [duplicate] - c

Example
#define Echo(a) a
#define Echo(a) (a)
I realize there probably isn’t a significant difference here, but why would you ever want to include the a within parenthesis inside the macro body? How does it alter it?

Suppose you have
#define mul(x, y) x * y
What happens if I say:
mul(a + 5, 6); /* a + 5 * 6 */
Now if I slighlty change the macro:
#define mul(x, y) ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */
Remember, the arguments aren't evaluated or anything, only textual substitution is performed.
EDIT
For an explanation about having the entire macro in parentheses, see the link posted by Nate C-K.

Just for the record, I landed from Here How to fix mathematical errors while using macros and I will try to expand this Answer here to fit the Other one.
You are asking about the difference about:
#define Echo( a ) a
#define Echo( a ) ( a )
which is fine as long as you do not understand the macro it self (I am not an expert too :) ).
First of all you already (probably) know that there is Operator Precedence, so there is a huge difference of this two programs:
1):
#include <stdio.h>
#define ADD( a , b ) a + b
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 2 + b );
printf( "%d", c );
return 0;
}
Output:
19
and:
#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( a , b );
printf( "%d", c );
return 0;
}
Output:
15
Now lets preplace + with *:
#define ADD( a, b ) a * b
The compiler treats a * b like for example a == 5 and b == 10 which does 5 * 10.
But, when you say:
ADD ( 2 + a * 5 + b )
Like here:
#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 5 + b );
printf( "%d", c );
return 0;
}
You get 105, because the operator precedence is involved and treats
2 + b * 5 + a
as
( 2 + 5 ) * ( 5 + 10 )
which is
( 7 ) * ( 15 ) == 105
But when you do:
#include <stdio.h>
#define ADD( a, b ) a * b
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 5 + b );
printf( "%d", c );
return 0;
}
you get 37 because of
2 + 5 * 5 + 10
which means:
2 + ( 5 * 5 ) + 10
which means:
2 + 25 + 10
Short answer, there is a big difference between:
#define ADD( a , b ) a * b
and
#define ADD( a , b ) ( a ) * ( a )

Related

How to calculate how many times a function is inside another function, for example g(9) inside g(k)

I am performing an activity, which is based on the recursive function, but I cannot understand how to put a part in code format. The code is this :
#include <stdio.h>
int count;
int g( int x ) {
count++;
if ( x == 0 )
return 2;
if ( x <= 2 )
return x * x;
if ( x <= 5 )
return x * g( x - 1 );
return (g( x - 3 ) + g( x - 2 ) );
}
int main () {
int k = 15;// random number
count = 0;
printf( " g(%d) = %d\n", k, g( k ) );
printf( " count: %d\n", count);
printf( " g(9) appeared : %d time(s) inside g(%d)",...,k);// in this space would be the other variable
return 0;
}
What I don't understand is how to calculate how many times, for example g(9), appears inside g(k). I've already made some attempts, but it never arrives at what is really requested. Thanks in advance

Performance of n-section root finding algorithm

I wrote a n-section algorithm for finding roots of a function. The working principle is exactly the same as is bisection method, only the range is divided into N equal parts instead. This is my C code:
/*
Compile with: clang -O3 -o nsect nsect.c -Wall -DCOUNT=5000000 -DNSECT=? -funroll-loops
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#define N 6
#ifndef COUNT
#error COUNT not defined!
#endif
#ifndef NSECT
#define NSECT 2
#endif
float polynomial[N];
float horner( const float poly[N], float x )
{
float val = poly[N-1];
for ( int i = N - 2; i >= 0; i-- )
val = poly[i] + x * val;
return val;
}
float f( float x )
{
return horner( polynomial, x );
}
float nsect( float a, float b, const float eps_x )
{
float fa = f( a );
float fb = f( b );
if ( fa == 0 ) return a;
else if ( fb == 0 ) return b;
else if ( fa * fb > 0 ) return 0;
float x[NSECT];
float fx[NSECT];
while ( b - a > eps_x )
{
x[0] = a;
if ( ( fx[0] = f( x[0] ) ) == 0 ) return x[0];
int found = 0;
for ( int i = 0; i < NSECT - 1; i++ )
{
x[i + 1] = a + ( b - a ) * (float)( i + 1 ) / NSECT;
if ( ( fx[i + 1] = f( x[i + 1] ) ) == 0 )
return x[i + 1];
else if ( fx[i] * fx[i + 1] < 0 )
{
a = x[i];
b = x[i + 1];
found = 1;
break;
}
}
if ( !found )
a = x[NSECT - 1];
}
return ( a + b ) * 0.5f;
}
int main( int argc, char **argv )
{
struct timeval t0, t1;
float *polys = malloc( COUNT * sizeof( float ) * N );
float *p = polys;
for ( int i = 0; i < COUNT * N; i++ )
scanf( "%f", p++ );
float xsum = 0; // So the code isn't optimized when we don't print the roots
p = polys;
gettimeofday( &t0, NULL );
for ( int i = 0; i < COUNT; i++, p += N )
{
memcpy( polynomial, p, N * sizeof( float ) );
float x = nsect( -100, 100, 1e-3 );
xsum += x;
#ifdef PRINT_ROOTS
fprintf( stderr, "%f\n", x );
#endif
}
gettimeofday( &t1, NULL );
fprintf( stderr, "xsum: %f\n", xsum );
printf( "%f ms\n", ( ( t1.tv_sec - t0.tv_sec ) * 1e6 + ( t1.tv_usec - t0.tv_usec ) ) * 1e-3 );
free( polys );
}
EDIT: This is the command I used to compile the code: clang -O3 -o nsect nsect.c -Wall -DCOUNT=5000000 -DNSECT=? -funroll-loops.
I ran everything on i7-8700k.
I decided to test the algorithm performance for different N values. The test consists of measuring time needed to find any root in range (-100;100) for each of 5,000,000 polynomials of degree 5. The polynomials are randomly generated and have real coefficients ranging from -5 to 5. The polynomial values are calculated using Horner's method.
These are results I got from running the code 10 times for each N (x=N, y=time [ms]):
My understanding of the worst case performance here is that the amount of work to be done in the main while loop is proportional to N. The main loop needs logN(C) (where C > 1 is a constant - ratio of initial search range to requested accuracy) iterations to complete. This yields following equation:
The plot looks very similar to the violet curve I used above to roughly match the data:
Now, I have some (hopefully correct) conclusions and questions:
Firstly, is my approach valid at all?
Does the function I came up with really describe the relation between number of operations and N?
I think this is the most interesting one - I'm wondering what causes such significant difference between N=2 and all the others? I consistently get this pattern for all my test data.
Moreover:
That function has minimum in e&approx;2.718..., which is closer to 3 than to 2. Also, f(3) < f(2) holds. Given that the equation I came up with is correct, I think that would imply that trisection method may actually be more efficient than bisection. It seems a bit counter intuitive, but the measurements seem to acknowledge that. Is this right?
If so, why does trisection method seem to be so unpopular compared to bisection?
Thank you
I am commenting on the general question, not on your particular code, which I don't fully understand.
Assuming that there is a single root known to be in an interval of length L and the desired accuracy is ε, you will need log(L/ε)/log(N) subdivision stages. Every subdivision stage requires N-1 evaluations of the function (not N), to tell which subinterval among N contains the root.
Hence, neglecting overhead, the total cost is proportional to (N-1)/log(N). The values of this ratio are, starting from N=2:
1.44, 1.82, 2.16, 2.49, 2.79...
and higher.
Hence the theoretical optimum is with N=2. This is why trisection is not used.

Palindromic numbers in C, string error

New to C. Trying to write program that prints out palindromic numbers < 1 million.
Prints out jibberish. Have I made an error with strings?
int decimal_pali(int x)
{
int digits=0;
int num=x;
char D[7];
while(num>0)
{
D[digits]=num%10;
digits+=1;
num/=10;
}
D[digits]='\0';
num=atoi(D);
if(num == x)
{
return 1;
}
return 0;
}
Your mistake lies here:
D[digits]=num%10;
It should be
D[digits] = num%10 + '0';
num % 10 will result in a number between 0 and 9 inclusive but since you are working with characters, you need to get the ASCII value of the digit. If you have a look at the ASCII table, you'll find that in order to achieve what you want, you need to add the ASCII value of '0' (48) to the value to get the correct character.
Curiosity wouldn't let me resist the "more than one base" thing, though I doubt the result has any (non-trivial) number-theoretic significance. Anyway, here's the code, and a sample run below that...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( int argc, char *argv[] ) {
int n1 = ( argc>1? atoi(argv[1]) : 1 ),
n2 = ( argc>2? atoi(argv[2]) : 999 ),
b1 = ( argc>3? atoi(argv[3]) : 10 ),
b2 = ( argc>4? atoi(argv[4]) : 10 );
int n=n1, b=b1, ispal();
char *itoa();
for ( n=n1; n<=n2; n++ ) {
for ( b=b1; b<=b2; b++ ) if ( !ispal(n,b) ) goto next_n;
printf("%10d(base10)",n);
for ( b=b1; b<=b2; b++ ) printf(" = %s(%d)", itoa(n,b),b);
printf("\n");
next_n: ; }
} /* --- end-of-function main() --- */
int ispal ( int i, int base ) {
char *itoa(), *a=itoa(i,base);
int answer=0, k=0,n=strlen(a);
if ( n > 1 ) {
for ( k=0; k<n/2; k++ )
if ( a[k] != a[n-k-1] ) goto end_of_job;
answer = 1; }
end_of_job: return ( answer );
} /* --- end-of-function ispal() --- */
char *itoa ( int i, int base ) {
static char a[99], digits[99] = /* up to base 65 */
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$*";
int n = 0;
while ( 1 ) {
a[n++] = digits[i%base];
if ( (i/=base) < 1 ) break; }
a[n] = '\000';
return ( a );
} /* --- end-of-function itoa() --- */
I called it palinum.c, and a typical run gives...
bash-4.3$ ./palinum 1 9999999 3 4
10(base10) = 101(3) = 22(4)
130(base10) = 11211(3) = 2002(4)
11950(base10) = 121101121(3) = 2322232(4)
175850(base10) = 22221012222(3) = 222323222(4)
749470(base10) = 1102002002011(3) = 2312332132(4)
1181729(base10) = 2020001000202(3) = 10200200201(4)
showing just a few numbers between 1 and 10million that are "palindromic" in both base 3 and base 4. The few other tests I did showed nothing simultaneously palindromic in three consecutive bases. But the program's easily changed to permit any set of (non-consecutive) bases. (For a less trivial programming challenge, try multiple threads for several n's at a time.)

Macro inside Macro

Consider the following code:
#define P1(x) x+x
#define P2(x) 2*P1(x)
int main()
{
int a = P1(1) ? 1 : 0;
int b = P2(a)&a;
return 0;
}
Now, I thought that the compiler first replacing the macros with their values and so int b = 2*a+a&a; (and since a=1 then b=3). Why isn't it so?
This is because & has lower precedence than that of addition + operator. The grouping of operands will take place as
int b = ( (2*a + a) & a );
Therefore, (2*a + a) = 3 and 3 & 1 = 1 (011 & 001 = 001).
There's no precedence in your operation (it is just a textual substitution) thus, as you've noted,
#define P1(x) x+x
#define P2(x) 2*P1(x)
int a = P1(1) ? 1 : 0; // 1
and since & has lower precedence than +, it is equivalent to
int b = ((2 * a) + a) & a;
i.e. only the rightmost bit is set on b.
((2 * a) + a) 011 &
a 001 =
--------------------
b 001

C macros and use of arguments in parentheses

Example
#define Echo(a) a
#define Echo(a) (a)
I realize there probably isn’t a significant difference here, but why would you ever want to include the a within parenthesis inside the macro body? How does it alter it?
Suppose you have
#define mul(x, y) x * y
What happens if I say:
mul(a + 5, 6); /* a + 5 * 6 */
Now if I slighlty change the macro:
#define mul(x, y) ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */
Remember, the arguments aren't evaluated or anything, only textual substitution is performed.
EDIT
For an explanation about having the entire macro in parentheses, see the link posted by Nate C-K.
Just for the record, I landed from Here How to fix mathematical errors while using macros and I will try to expand this Answer here to fit the Other one.
You are asking about the difference about:
#define Echo( a ) a
#define Echo( a ) ( a )
which is fine as long as you do not understand the macro it self (I am not an expert too :) ).
First of all you already (probably) know that there is Operator Precedence, so there is a huge difference of this two programs:
1):
#include <stdio.h>
#define ADD( a , b ) a + b
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 2 + b );
printf( "%d", c );
return 0;
}
Output:
19
and:
#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( a , b );
printf( "%d", c );
return 0;
}
Output:
15
Now lets preplace + with *:
#define ADD( a, b ) a * b
The compiler treats a * b like for example a == 5 and b == 10 which does 5 * 10.
But, when you say:
ADD ( 2 + a * 5 + b )
Like here:
#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 5 + b );
printf( "%d", c );
return 0;
}
You get 105, because the operator precedence is involved and treats
2 + b * 5 + a
as
( 2 + 5 ) * ( 5 + 10 )
which is
( 7 ) * ( 15 ) == 105
But when you do:
#include <stdio.h>
#define ADD( a, b ) a * b
int main( void )
{
auto const int a = 5;
auto const int b = 10;
auto const int c = ADD ( 2 + a , 5 + b );
printf( "%d", c );
return 0;
}
you get 37 because of
2 + 5 * 5 + 10
which means:
2 + ( 5 * 5 ) + 10
which means:
2 + 25 + 10
Short answer, there is a big difference between:
#define ADD( a , b ) a * b
and
#define ADD( a , b ) ( a ) * ( a )

Resources