Use wider than int
math to handle range limitations.
Find absolute value by division trick.1
((3 * d) / (3 * d + 1)) --> 0 when d >= 0
((3 * d) / (3 * d + 1)) --> -1 when d < 0
No conditions used.
long long my_abs_diff(long long a, long long b) {
long long d = 0LL + a - b;
return d * (1 - 2 * ((3 * d) / (3 * d + 1)));
}
long long my_min(long long a, long long b) {
return ((a + b) - my_abs_diff(a, b)) / 2;
}
long long my_max(long long a, long long b) {
return ((a + b) + my_abs_diff(a, b)) / 2;
}
int median3(int a, int b, int c) {
long long mn = my_min(my_min(a, b), c);
long long mx = my_max(my_max(a, b), c);
return (int) (-mn - mx + a + b + c);
}
Simplification may exist.
1In C, since C99, integer division is defined as truncating towards zero. It is this directed-ness towards zero code is exploiting to effect an "if". A cost to this approach is that we need a few more bits of integer range. For pre-C99, code can use div()
to insure the desired quotient truncation.
Tested successfully with many edge cases and 10,000,00,00 random combinations over entire int
range: [INT_MIN
... INT_MAX
].