2

I've been given the task of defining a macro to take three numbers as parameters and return their median

#define MEDIAN(x,y,z) (??)

I can't think of an easy way to do this without a long sequence of if statements to determine the middle element, as I can't use library functions either.

Any hints?

Tobi3
  • 147
  • 1
  • 1
  • 6

5 Answers5

4

Use conditional expressions to shorten things. Here's one for finding the minimum of two values.

#define MIN(x,y)    (((x) < (y)) ? (x) : (y))

However, it's normally frowned upon to have lots of nested conditional expressions.

Note: As you're writing a macro rather than a function, you'll have trouble if the user passes in e.g. i++.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • I started with this, and I'm aware of macro issues but without many nested conditional expressions is there a way to do it? – Tobi3 May 17 '12 at 15:36
  • @Tobi3: Not really. Fundamentally, there are 6 different situations you need to be able to distinguish; this necessarily involves a number of comparisons. – Oliver Charlesworth May 17 '12 at 15:59
2
/* May not be the best implementation but it covers all corner cases of three 
different numbers.  */  
#define MEDIAN(x,y,z) \  
    (((x) > (y) && (x) < (z)) || ((x) < (y) && (x) > (z))) ?  \  
            ((x)) : \  
            ((x) < (y) ? ((y) < (z) ? (y) : (z)) : ((y) > (z) ? (y) : (z)))  
0

I tryed this and it worked for me:

#define MAXVAL(val1,val2)  ((val1>val2) ?  (val1):(val2) )
#define MINVAL(val1,val2)  ((val1<val2) ?  (val1):(val2) )
#define MEDIAN3(val1,val2,val3) MINVAL(MINVAL(MAXVAL(val1,val2),MAXVAL(val2,val3)),MAXVAL(val3,val1))

But since you need to sort the values to get the median I think some kind of simple bubble sort algorithm (http://de.wikipedia.org/wiki/Bubblesort) for 3 values should be the best solution.

-- EDIT --

This is a better solution:

#define MEDIAN3(val1,val2,val3) MAXVAL(MINVAL(MAXVAL(val1,val2),val3),MINVAL(val1,val2))

and minimal of 3 values macro:

#define MIN3(x,y,z) ( ( y ) <= ( z ) ? ((x) <= (y) ? (x) : (y)) : ((x) <= (z) ? (x) : (z)))
jamk
  • 836
  • 1
  • 10
  • 24
0

I have two macros (or at least found two) for you:

#define MEDIAN(a,b,c) ((a > b) ? (b > c) ? b : (a > c) ? c : a : \
                       (b > c) ? (a > c) ? a : c : b)

and

#define MEDIAN(a,b,c) ((a-b)*(b-c) > 1 ? b : ((a-b)*(a-c) < -1 ? a : c))
Sriram Murali
  • 5,804
  • 2
  • 26
  • 32
-2

There. It checks all the six conditions for finding the MEDIAN. I did it quickly, I'm sure can be improved further.

#define MEDIAN(x, y, z) (x <= y ? (z < x ? x : \
        (z > y ? y : z)) : (z < y ? y : (z > x ? x : z)))
Shivam
  • 2,134
  • 1
  • 18
  • 28
  • 1
    It's generally frowned upon to just do people's homework for them on Stack Overflow... – Oliver Charlesworth May 17 '12 at 16:46
  • @Tobi3 Note that if you're forced to use a macro, then expressions with side-effects like `MEDIAN(value, ++value, ++value)` and its ilk will return wonky results. The expressions will be textually substituted and run multiple times. Macros are "bad". Well, almost always. http://stackoverflow.com/questions/96196/when-are-c-macros-beneficial – HostileFork says dont trust SE May 31 '12 at 04:00