Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest min max among three floats in C

I think the question is pretty clear: I have three numbers, I have two functions, min and max.

What are the fastest implementations?

like image 243
Zaki Mohzani Avatar asked Nov 15 '11 11:11

Zaki Mohzani


4 Answers

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));
like image 80
Frerich Raabe Avatar answered Sep 29 '22 06:09

Frerich Raabe


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.

like image 34
Adam Zalcman Avatar answered Oct 01 '22 06:10

Adam Zalcman


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 :)

like image 34
Pradeep Nayak Avatar answered Sep 29 '22 06:09

Pradeep Nayak


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 ...)

like image 35
Useless Avatar answered Sep 28 '22 06:09

Useless