Find maximum of three number in C without using conditional statement and ternary operator

前端 未结 13 1804
日久生厌
日久生厌 2020-11-29 22:25

I have to find maximum of three number provided by user but with some restrictions. Its not allowed to use any conditional statement. I tried using ternary operator like bel

相关标签:
13条回答
  • 2020-11-29 23:00

    Taking advantage of short-circuiting in boolean expressions:

    int max(int a, int b, int c)
    {
         int m = a;
         (m < b) && (m = b); //these are not conditional statements.
         (m < c) && (m = c); //these are just boolean expressions.
         return m;
    }
    

    Explanation:

    In boolean AND operation such as x && y, y is evaluated if and only if x is true. If x is false, then y is not evaluated, because the whole expression would be false which can be deduced without even evaluating y. This is called short-circuiting when the value of a boolean expression can be deduced without evaluating all operands in it.

    Apply this principle to the above code. Initially m is a. Now if (m < b) is true, then that means, b is greater than m (which is actually a), so the second subexpression (m = b) is evaluated and m is set to b. If however (m < b) is false, then second subexpression will not be evaluated and m will remain a (which is greater than b). In a similar way, second expression is evaluated (on the next line).

    In short, you can read the expression (m < x) && (m = x) as follows : set m to x if and only if m is less than x i.e (m < x) is true. Hope this helps you understanding the code.

    Test code:

    int main() {
            printf("%d\n", max(1,2,3));
            printf("%d\n", max(2,3,1));
            printf("%d\n", max(3,1,2));
            return 0;
    }
    

    Output:

    3
    3
    3
    

    Note the implementation of max gives warnings because evaluated expressions are not used:

    prog.c:6: warning: value computed is not used
    prog.c:7: warning: value computed is not used

    To avoid these (harmless) warnings, you can implement max as:

    int max(int a, int b, int c)
    {
         int m = a;
         (void)((m < b) && (m = b)); //these are not conditional statements.
         (void)((m < c) && (m = c)); //these are just boolean expressions.
         return m;
    }
    

    The trick is that now we're casting the boolean expressions to void, which causes suppression of the warnings:

    0 讨论(0)
  • 2020-11-29 23:01

    No conditional statements, just loops and assignments. And completely different form others' answers :)

    while (a > b)
    {
        while (a > c)
        {
            tmp = a;
            goto finish;
        }
        tmp = c;
        goto finish;
    }
    while (b > c)
    {
        tmp = b;
        goto finish;
    }
    tmp = c;
    finish: max = tmp;
    
    0 讨论(0)
  • 2020-11-29 23:12

    Try this.

    #include "stdio.h"
    main() {
        int a,b,c,rmvivek,arni,csc; 
        printf("enter the three numbers");
        scanf("%d%d%d",&a,&b,&c);
        printf("the biggest value is %d",(a>b&&a>c?a:b>c?b:c));
    }
    
    0 讨论(0)
  • 2020-11-29 23:14

    UPDATE: Looking at this 4 years later, I see that it fails badly if two or more of the values happen to be equal. Replacing > by >= changes the behavior, but doesn't fix the problem. It might still be salvageable, so I won't delete it yet, but don't use this in production code.


    Ok, here's mine:

    int max3(int a, int b, int c)
    {
        return a * (a > b & a > c) +
               b * (b > a & b > c) +
               c * (c > a & c > b);
    }
    

    Note that the use of & rather than && avoids any conditional code; it relies on the fact that > always yields 0 or 1. (The code generated for a > b might involve conditional jumps, but they're not visible from C.)

    0 讨论(0)
  • 2020-11-29 23:15

    Boolean valued operators (including <, &&, etc) typically translate to conditional operations at the machine code level, so don't fulfill the spirit of the challenge. Here's a solution that any reasonable compiler would translate to only arithmetic instructions with no conditional jumps (assuming long has more bits than int and that long is 64 bits). The idea is that "m" captures and replicates the sign bit of b - a, so m is either all 1 bits (if a > b) or all zero bits (if a <= b). Note that long is used to avoid overflow. If for some reason you know that b - a doesn't over/under-flow, then the use of long isn't needed.

    int max(int a, int b)
    {
        long d = (long)b - (long)a;
        int m = (int)(d >> 63);
        return a & m | b & ~m;
    }
    
    int max(int a, int b, int c)
    {
        long d;
        int m;
        d = (long)b - (long)a;
        m = (int)(d >> 63);
        a = a & m | b & ~m;
        d = (long)c - (long)a;
        m = (int)(d >> 63);
        return a & m | c & ~m;
    }
    
    0 讨论(0)
  • 2020-11-29 23:17
    int fast_int_max(int a, int b)
    {
        int select= -(a < b);
        unsigned int b_mask= select, a_mask= ~b_mask;
    
        return (a&a_mask)|(b&b_mask);
    }
    
    int fast_int_max3(int a, int b, int c)
    {
        return fast_int_max(a, fast_int_max(b, c));
    }
    
    0 讨论(0)
提交回复
热议问题