'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 |
