'Function to return median of 3

I am looking for the best solution to finding a median of 3. I want it to be in the least lines possible. Thank you in advance :) I've tried sth like this:

int median(int a, int b, int c)
{
    if ((a >= b && a <= c) || (a <= b && a >= c)) return a;
    if ((b >= a && b <= c) || (b <= a && b >= c)) return b;
    return c;
}

I believe this solution is okay, but maybe there is something better?



Solution 1:[1]

How about

int median(int a, int b, int c) {
    std::vector<int> result = { a,b,c };
    std::sort(result.begin(), result.end());
    return result[1];
}

Solution 2:[2]

This should work for all platform int values, and supports duplicates (e.g. cases of two, or all three arguments being equivalent).

int median(int a, int b, int c) 
{
    return ((a > b) ^ (a > c)) ? a : ((b < a) ^ (b < c)) ? b : c;
}

Example O2 optimized asm:

clang 12.0.1

median:
    mov     eax, edx
    cmp     edi, esi
    setg    r8b
    cmp     edi, edx
    setg    dl
    xor     dl, r8b
    cmp     esi, eax
    setl    cl
    xor     cl, r8b
    cmovne  eax, esi
    test    dl, dl
    cmovne  eax, edi
    ret

gcc 11.2

median:
    cmp     edi, esi
    mov     eax, edi
    setg    cl
    cmp     edi, edx
    setg    dil
    cmp     cl, dil
    je      .L5
    ret

.L5:
    cmp     esi, edx
    setl    al
    cmp     cl, al
    mov     eax, edx
    cmovne  eax, esi
    ret

Solution 3:[3]

Short can be cryptic to read:

return a < b ? c < a ? a : b < c ? b : c : c < b ? b : a < c ? a : c;

I can add redundant parentheses to clarify but unsure if it clarifies anything:

return a < b ? (c < a ? a : b < c ? b : c) : c < b ? b : a < c ? a : c;

Solution 4:[4]

Enumerating all possibilities is certainly one way. But we can also factor out a comparison - after all, the result of a < b already tells you the relative ordering of those two.

int median3(int a, int b, int c) {
    // Sort a and b
    int lo, hi;
    if (a <= b) {
        lo = a;
        hi = b;
    } else {
        lo = b;
        hi = a;
    }

    // Check where c lies relative to hi & lo
    if (c > hi) {
        return hi;
    } else if (c < lo) {
        return lo;
    } else {
        return c;
    }
}

Whether to consider this "better" (or more readable) is probably a matter of taste.

Solution 5:[5]

int getMedian(int a, int b , int c) {
    int p = a-b,q=b-c,r=a-c;
    if(p*q > 0) return b;
    return p*r > 0?c:a;
}

This will do

Solution 6:[6]

first google search: https://www.geeksforgeeks.org/middle-of-three-using-minimum-comparisons/

after some more search found this: Fastest way of finding the middle value of a triple?

median = max(min(a,b), min(max(a,b),c));

Solution 7:[7]

The best implementation is clearly a question of taste.

When possible, I prefer to manipulate boolean expressions, and to limit the number of comparisons.

#include <iostream>
int median (int a, int b, int c) {
    auto tab = (a < b), tac = (a < c), tbc = (b < c);
    if (tab xor tac) return a;
    if (!tab xor tbc) return b;
    return c;
}
int main() {
    std::cout << median (1, 2, 3) << std::endl;
    std::cout << median (1, 3, 2) << std::endl;
    std::cout << median (2, 1, 3) << std::endl;
    std::cout << median (2, 3, 1) << std::endl;
    std::cout << median (3, 2, 1) << std::endl;
    std::cout << median (3, 1, 2) << std::endl;
    std::cout << median (1, 2, 2) << std::endl;
    std::cout << median (2, 2, 3) << std::endl;
    std::cout << median (2, 2, 1) << std::endl;
    return 0;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Diamaudix Audio Ltd.
Solution 2 WhozCraig
Solution 3
Solution 4 Benjamin Maurer
Solution 5 Giriteja Bille
Solution 6 Anton
Solution 7 Damien