I think the question is pretty clear: I have three numbers, I have two functions, min and max.
What are the fastest implementations?
The C standard (C99) provides the fmaxf
and fminf
functions in the standard C math.h header. I'd start by just using it to find the largest of three floats and then check whether it's fast enough for your needs:
float max = fmaxf(a, fmaxf(b, c));
float min = fminf(a, fminf(b, c));
Naive solution is two use two comparisons to find the min and then two comparisons to find the max. This is suboptimal since three comparisons suffice (pseudocode returning (min, max) tuple follows):
function minmax(float a, float b, float c): (float, float)
begin
boolean altb = (a < b);
boolean bltc = (b < c);
if altb and bltc then return (a, c);
if not altb and not bltc then return (c, a);
if altb then // Also: c <= b, so b is known to be max
begin
if a < c then return (a, b);
return (c, b);
end
if bltc then // Also: b <= a, so b is known to be min
begin
if a < c then return (b, c);
return (b, a);
end
// Unreachable.
end
(This is written to be most readable, rather than to minimize the branch count)
This performs between 2 and 3 comparisons. It is impossible to use only 2 comparisons since there are 3! = 6 reorderings of 3 floats and 2 comparisons can only differentiate between 4 different ones. This is easily seen on a decision tree of the problem.
In practice one should rely for optimizations like this one on the compiler.
Code to find the greatest of three numbers.
#includ<stdio.h>
void main()
{
float a,b,c;
printf("enter a,b,c:");
scanf("%f%f%f",&a,&b,&c);
printf("Greatest no: %f"(a>b)?((a>c)?a:c):((c>b)?c:b));
}
Reverse the logic to find the least :)
I liked Adam Zalcman's approach so much, I rewrote it in C, this time minimising branches too (so at most 3 comparisons and 3 branches).
struct Pair
{
float min_value;
float max_value;
};
struct Pair minmax(float a, float b, float c)
{
/* truth table:
* a<b b<c a<c
* T T * => (a, c)
* T F T => (a, b)
* T F F => (c, b)
* F T T => (b, c)
* F T F => (b, a)
* F F * => (c, a)
*/
if (a < b) {
if (b < c)
return (struct Pair) {a, c};
else {
if (a < c)
return (struct Pair) {a, b};
else
return (struct Pair) {c, b};
}
} else {
if (b < c) {
if (a < c)
return (struct Pair) {b, c};
else
return (struct Pair) {b, a};
} else
return (struct Pair) {c, a};
}
}
void foo()
{
struct Pair result = minmax(1.0, 2.0, 3.0);
}
(this may be degenerating into code golf now though ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With