Take the 2-minute tour ×

Consider three values x, y, z.

What would be the formula to get the mid value (not the mean value but the value which is neither the min nor the max)?

const double min = std::min(x, std::min(y, z));
const double mid = /* what formula here ? */
const double max = std::max(x, std::max(y, z));
share|improve this question
Maybe there isn't a neat symmetrical formula? –  Oliver Charlesworth May 4 at 10:49
@AbhishekBansal What if they are all equal? What if only two of them are equal? –  n.m. May 4 at 10:52
FYI this is called a median. Related. –  n.m. May 4 at 10:56
Just pick any one at random. Your app will then work 1/3 of the time, which is much more than my current app is achieving. –  Martin James May 4 at 11:02
BTW, in C++11, min can be rewritten std::min({x, y, z}). –  Jarod42 May 4 at 14:31

6 Answers 6

up vote 11 down vote accepted

The answer from this link shared in the comments:

const double mid = std::max(std::min(x,y),std::min(std::max(x,y),z));

Edit - As pointed out by Alan, I missed out on a case. I have given now a more intuitive proof.

Direct Proof: Without Loss of Generality with respect to x and y.
Starting with the innermost expression, min(max(x,y),z) ...

  1. If it returns z, we have found the relations: max(x,y) > z. Then the expression evaluates to max(min(x,y),z). Through this we are able to determine the relation between min(x,y) and z.
    If min(x,y) > z, then z is smaller than x and y both (as the relation becomes: max(x,y) > min(x,y) > z). Therefore the min(x,y) is indeed the median and max(min(x,y),z) returns that.
    If min(x,y) < z, then z is indeed the median (as min(x,y) < z < max(x,y)).

  2. If it returns x, then we have x < z and y < z. The expressions evaluates to: max(min(x,y),x). Since max(x,y) evaluated to x, min(x,y) evaluates to y. Getting the relation z > x > y. We return the max of x and y (as the expression becomes max(y,x)) which is x and also the median. (Note that the proof for y is symmetrical)

Proof Ends

Old Proof - Note it is NOT complete (Direct):

Without loss of generality: Assume x > y > z
Min of x and y is y. And min of (max of x and y) and z is z.
The max of y and z is y which is the median.

Assume x = y > z
Min of x and y say is x. And min of (max of x and y is x) and z is z.
Max of the above two is x, which is the median.

Assume x > y = z
Max of the above two is y, which is the median.

Finally, assume x = y = z
Any of the three numbers will be the median., and the formula used will return some number.

share|improve this answer
Yes, it works. However, it is not very readable and consequently would be difficult to maintain; at first glance it is not clear what is happening. In contrast, with my solution 'auto mid = median(x,y,z)', it is instantly recognizable that the function returns the median of the three values. –  Ricky65 May 6 at 12:02
I'm not entirely convinced by your proof. What about the case where x < y < z? (You say "without loss of generality" - but the expression is not symmetric in the three values.) However, I believe the code is correct. –  Alan Stokes May 10 at 13:39
@AlanStokes Good catch. I will look into it, and improve the answer. (possibly try to give a more elegant proof if possible). –  digvijay91 May 10 at 13:53

To find all three at once in a symmetrical fashion:

min = x; med = y; max = z;

if (min > med) std::swap(min, med);
if (med > max) std::swap(med, max);
share|improve this answer
Isn't this a kind of Bubble sort? –  user1990169 May 4 at 11:06
This will not work in C though, just saying. :) –  lpapp May 4 at 11:08
@AbhishekBansal this is indeed bubble sort. –  n.m. May 4 at 11:08
@LaszloPapp: Question is only tagged C++... –  Oliver Charlesworth May 4 at 12:07
@OliCharlesworth: I know right. I hate to ask this: so what? I cannot say that it will not work in C? What do you think "just saying" means? ;) –  lpapp May 4 at 12:13

This seems like cheating, but: x + y + z - min - max

share|improve this answer
Nice trick, Alan. ;) –  lpapp May 4 at 10:52
I like it. The only problem would be overflow. –  keyser May 4 at 10:52
This is clever, but introduces numerical errors. –  Anonymous May 4 at 10:52
@keyser: true, so it is worth posting a different answer, too, just in case. Also, this is not necessarily returning the variable, just the value. –  lpapp May 4 at 10:53
It is a solution which may give a 4th number ^_^ (ideone.com/NYxgho) –  Jarod42 May 4 at 14:29

It is a bit uglier than Alan's trick, but it cannot cause overflow, nor numerical errors, and so on:

int x, y, z, median;

if (x <= y && y <= z || y >= z && y <= x) median = y;
else if (y <= x && x <= z || x >= z && x <= y) median = x;
else median = z;

The algorithm is simply this:

  • check if x is between y and z, if yes, that is it.

  • check if y is between x and z, if yes, that is it.

  • It must be z since it was neither x, nor y.


You could also get this more flexibly if you have more than three elements, with sorting.

// or xor implementation, does not matter...

void myswap(int* a, int* b) { int temp = *b; *b = *a; *a = temp; }

int x, y, z;
// Initialize them
int min = x;
int med = y;
int max = z;

// you could also use std::swap here if it does not have to be C compatible
// In that case, you could just pass the variables without the address operator.
if (min > med) myswap(&min, &med);
if (med > max) myswap(&med, &max);
share|improve this answer
If you want all three (min, mid, max), just sorting the list is probably best. One comparison and swap to get the first two in order, then at most two tests to work out the order of the other two. –  Alan Stokes May 4 at 11:04
Yes, although that would be a specific solution, and this solution will also work in C unlike std::swap. :P –  lpapp May 4 at 11:05
True - although the general algorithm for finding the median (or nth_greatest) is based on quick sort, but skipping unnecessary work. –  Alan Stokes May 4 at 11:06
@AlanStokes: sure, I agree. This version is optimized for readability and compreheniveness, while that one is for efficiency and flexibility. There is no efficiency problem here and the OP seems to be asking about three values, however, so I think both are valid. But yeah, sorting works gently for more than 3 elements, too; just need to make sure about odd numbers. –  lpapp May 4 at 11:07
@AlanStokes: updated a swap sorting version (i.e. bubble sort) with C compatibility, just in case. :D –  lpapp May 4 at 11:16

A variant of Alan's "cheat" that (kind of and sometimes) prevents overflow:

#include <iostream>
#include <algorithm>

using namespace std;
    double a = 1e308;
    double b = 6e306;
    double c = 7.5e18;

    double mn = min(a,min(b,c));
    double mx = max(a,max(b,c));
    double avg = mn + (mx-mn)*0.5;
    double mid = a - avg + b - avg + c;

    cout << mid << endl;



It makes use of the avg-formula often used in binary search to prevent overflow:

The average of two values can be calculated as low + (high-low)/2

However, it only works for positive values. Possible fallbacks include Alan's answer, or simply (x+y)/2 for the avg calculation.

Note that double precision comes into play here, and may cause issues in the mid-calculation. It works really well for positive integers though :)

share|improve this answer
The problem of not accessing the middle variable is still in there. –  lpapp May 4 at 11:09
@LaszloPapp That wasn't part of the question. It was about finding the value –  keyser May 4 at 11:25
No, it was not, but the readers can be made aware of the limitation of an algorithm. :) –  lpapp May 4 at 11:28
It's not a limitation, it's a specification :p Finding the variable is a completely separate issue according to me. I mean, it's wrong to call it a problem. –  keyser May 4 at 11:29
Note that Stack Overflow is used by many people and they might take algorithms from here into generic cases. Yes, you can say, "it is their problem", if they take it wrong, but preventing that is better IMHO. It is not to say, your answer is not usable, etc, of course. –  lpapp May 4 at 11:30

The best way to do this is with a generic median function template. No copying, swapping or mathematical operations are required.

template <typename T>
const T& median(const T& a, const T& b, const T& c)
    if (a < b)
        if (b < c)
            return b;
        else if (a < c)
            return c;
            return a;
    else if (a < c)
        return a;
    else if (b < c)
        return c;
        return b;
share|improve this answer
"The best way" is actually unreadable with the if/elseif/else jungle for a non-performance critical code. :) I think it is better to be comprehensive in such cases than micro optimization. Also, this will not fly with more than three elements when you need to calculate the median for odd amount of numbers.. –  lpapp May 4 at 11:58
imo it is not unreadable; it is elegant. You've probably just glanced at it for a few seconds and immediately declared it unreadable without putting enough thought into it. Also, he's only looking for the median of three values. –  Ricky65 May 4 at 12:05
I was actually considering templates before, but then I decided not to mention them because IMHO it is more complex than needed. Also, I do not see any non-negligible performance gain out of it. It is basically the templatized version of my first solution with different if/elseif/else ordering, but I am not sure about the gain of template here compared to my non-template code. To me, it seems to make it more complex than necessary. One thing I agree about is that it is useful if you have different types to deal with, so it is flexible in that sense. –  lpapp May 4 at 12:07

Your Answer


