Reputation: 21
I need to find the Max value with a macro beetween 55 values defined also as macro definitions. I mean
#define VALUE1 56
#define VALUE2 76
...
#define VALUE55 14
#define MAX_BEETWEEN_VALUES (...) ...
the macro function MAX_BEETWEEN_VALUES should return 76 as result. I can´t figure out how this macro should be coded.
Thanks for your help
Upvotes: 2
Views: 3168
Reputation: 48128
A novel (and fairly evil) approach to generating having many/max macros could be to generate them.
Example Python script:
def minmax(a, expr):
t = "("
t = t + ("(%s%s%s)?" % (a[0], expr, a[1]))
if len(a) == 2:
r_a = a[0]
r_b = a[1]
else:
r_a = minmax((a[0],) + a[2:], expr)
r_b = minmax(a[1:], expr)
t = t + ("%s:%s" % (r_a, r_b))
return t + ")"
for i in range(2, 8):
args = tuple([("v%d" % j) for j in range(i)])
print((" #define MIN%d(%s) " % (i, ",".join(args)) + minmax(args, "<")))
print((" #define MAX%d(%s) " % (i, ",".join(args)) + minmax(args, ">")))
generates this...
#define MIN2(v0,v1) ((v0<v1)?v0:v1)
#define MAX2(v0,v1) ((v0>v1)?v0:v1)
#define MIN3(v0,v1,v2) ((v0<v1)?((v0<v2)?v0:v2):((v1<v2)?v1:v2))
#define MAX3(v0,v1,v2) ((v0>v1)?((v0>v2)?v0:v2):((v1>v2)?v1:v2))
#define MIN4(v0,v1,v2,v3) ((v0<v1)?((v0<v2)?((v0<v3)?v0:v3):((v2<v3)?v2:v3)):((v1<v2)?((v1<v3)?v1:v3):((v2<v3)?v2:v3)))
#define MAX4(v0,v1,v2,v3) ((v0>v1)?((v0>v2)?((v0>v3)?v0:v3):((v2>v3)?v2:v3)):((v1>v2)?((v1>v3)?v1:v3):((v2>v3)?v2:v3)))
#define MIN5(v0,v1,v2,v3,v4) ((v0<v1)?((v0<v2)?((v0<v3)?((v0<v4)?v0:v4):((v3<v4)?v3:v4)):((v2<v3)?((v2<v4)?v2:v4):((v3<v4)?v3:v4))):((v1<v2)?((v1<v3)?((v1<v4)?v1:v4):((v3<v4)?v3:v4)):((v2<v3)?((v2<v4)?v2:v4):((v3<v4)?v3:v4))))
#define MAX5(v0,v1,v2,v3,v4) ((v0>v1)?((v0>v2)?((v0>v3)?((v0>v4)?v0:v4):((v3>v4)?v3:v4)):((v2>v3)?((v2>v4)?v2:v4):((v3>v4)?v3:v4))):((v1>v2)?((v1>v3)?((v1>v4)?v1:v4):((v3>v4)?v3:v4)):((v2>v3)?((v2>v4)?v2:v4):((v3>v4)?v3:v4))))
#define MIN6(v0,v1,v2,v3,v4,v5) ((v0<v1)?((v0<v2)?((v0<v3)?((v0<v4)?((v0<v5)?v0:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5))):((v2<v3)?((v2<v4)?((v2<v5)?v2:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5)))):((v1<v2)?((v1<v3)?((v1<v4)?((v1<v5)?v1:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5))):((v2<v3)?((v2<v4)?((v2<v5)?v2:v5):((v4<v5)?v4:v5)):((v3<v4)?((v3<v5)?v3:v5):((v4<v5)?v4:v5)))))
#define MAX6(v0,v1,v2,v3,v4,v5) ((v0>v1)?((v0>v2)?((v0>v3)?((v0>v4)?((v0>v5)?v0:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5))):((v2>v3)?((v2>v4)?((v2>v5)?v2:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5)))):((v1>v2)?((v1>v3)?((v1>v4)?((v1>v5)?v1:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5))):((v2>v3)?((v2>v4)?((v2>v5)?v2:v5):((v4>v5)?v4:v5)):((v3>v4)?((v3>v5)?v3:v5):((v4>v5)?v4:v5)))))
#define MIN7(v0,v1,v2,v3,v4,v5,v6) ((v0<v1)?((v0<v2)?((v0<v3)?((v0<v4)?((v0<v5)?((v0<v6)?v0:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6)))):((v2<v3)?((v2<v4)?((v2<v5)?((v2<v6)?v2:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))))):((v1<v2)?((v1<v3)?((v1<v4)?((v1<v5)?((v1<v6)?v1:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6)))):((v2<v3)?((v2<v4)?((v2<v5)?((v2<v6)?v2:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))):((v3<v4)?((v3<v5)?((v3<v6)?v3:v6):((v5<v6)?v5:v6)):((v4<v5)?((v4<v6)?v4:v6):((v5<v6)?v5:v6))))))
#define MAX7(v0,v1,v2,v3,v4,v5,v6) ((v0>v1)?((v0>v2)?((v0>v3)?((v0>v4)?((v0>v5)?((v0>v6)?v0:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6)))):((v2>v3)?((v2>v4)?((v2>v5)?((v2>v6)?v2:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))))):((v1>v2)?((v1>v3)?((v1>v4)?((v1>v5)?((v1>v6)?v1:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6)))):((v2>v3)?((v2>v4)?((v2>v5)?((v2>v6)?v2:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))):((v3>v4)?((v3>v5)?((v3>v6)?v3:v6):((v5>v6)?v5:v6)):((v4>v5)?((v4>v6)?v4:v6):((v5>v6)?v5:v6))))))
The macro doubles in length with each argument added, so I wouldn't recommend this for large arrays. however if all values are literals the compiler will likely resolve the result for you.
Upvotes: 1
Reputation: 56509
Hard code
#define MAX(X, Y) ((X>Y)?(X):(Y))
#define MAX_BEETWEEN_VALUES MAX(VALUE1, \
MAX(VALUE2, \
MAX(VALUE3, \
... \
MAX(VALUE54, \
VALUE55))) ... )
~~~~~~~~~ 54 close parenthesis
It may exceed compiler's limitations.
Upvotes: 1
Reputation: 4455
Here's another C kludge to find the maximum at compile-time. Assuming that enumerations work as well as #defines for you and that the values are small positive integers (though there are even worse workarounds for other domains).
union value_set_t {
# define V(name, value) char name##_[value];
# include "values.h"
# undef V
};
enum {
# define V(name, value) name = value,
# include "values.h"
# undef V
MAX_BETWEEN_VALUES = sizeof(union value_set_t)
};
With values.h:
V(VALUE1, 56)
V(VALUE2, 76)
V(VALUE55, 14)
Upvotes: 2
Reputation: 10343
Code for my comment to answer above: https://stackoverflow.com/a/20221017/2963099
V1 to V58 not shown
#define V59 1
#define V60 33
#define V61 1
#define V62 2
#define V63 1
#define V64 2
#define MAX2(a,b) ((a>b)?(a):(b))
#define MAX4(a,b,c,d) MAX2(MAX2(a,b), MAX2(c,d))
#define MAX8(a,b,c,d,e,f,g,h) MAX2(MAX4(a,b,c,d),MAX4(e,f,g,h))
#define MAX64(a1,a2,a3,a4,a5,a6,a7,a8, \
b1,b2,b3,b4,b5,b6,b7,b8, \
c1,c2,c3,c4,c5,c6,c7,c8, \
d1,d2,d3,d4,d5,d6,d7,d8, \
e1,e2,e3,e4,e5,e6,e7,e8, \
f1,f2,f3,f4,f5,f6,f7,f8, \
g1,g2,g3,g4,g5,g6,g7,g8, \
h1,h2,h3,h4,h5,h6,h7,h8) MAX8(\
MAX8(a1,a2,a3,a4,a5,a6,a7,a8), \
MAX8(b1,b2,b3,b4,b5,b6,b7,b8), \
MAX8(c1,c2,c3,c4,c5,c6,c7,c8), \
MAX8(d1,d2,d3,d4,d5,d6,d7,d8), \
MAX8(e1,e2,e3,e4,e5,e6,e7,e8), \
MAX8(f1,f2,f3,f4,f5,f6,f7,f8), \
MAX8(g1,g2,g3,g4,g5,g6,g7,g8), \
MAX8(h1,h2,h3,h4,h5,h6,h7,h8))
int main(int, char**)
{
int x= MAX64(V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,V20,V21,V22,V23,V24,V25,V26,V27,V28,V29,V30,V31,V32,V33,V34,V35,V36,V37,V38,V39,V40,V41,V42,V43,V44,V45,V46,V47,V48,V49,V50,V51,V52,V53,V54,V55,V56,V57,V58,V59,V60,V61,V62,V63,V64);
return x;
}
Compiles pretty quickly (and has 33 as correct answer)
Upvotes: 1
Reputation: 60383
There might be a standardized way, but if not it's easy enough to just do it, if you're willing to go the "a better C" route.
#include <cstdio>
template<int a, int ...list> struct greatest_of {
static const int value = a > greatest_of<list...>::value
? a : greatest_of<list...>::value;
};
template<int a> struct greatest_of<a> {
static const int value = a;
};
int main()
{
printf("%d\n",greatest_of<1,2,3>::value);
}
(edit: printf
).
Upvotes: 0