Thread: tertiary comparison

  1. #1
    Obsessed with C chrismiceli's Avatar
    Join Date
    Jan 2003
    Posts
    501

    tertiary comparison

    Is there an easy way to compare three variables or more for equality, and inequality? Let me explain.
    Code:
    if((x == y) && (y == z) && z != a) {
        //code
    }
    I am testing to see if x, y, and z are all equal, and none of them equal to a (part in italics).
    Help populate a c/c++ help irc channel
    server: irc://irc.efnet.net
    channel: #c

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Your way looks pretty good to me. What's wrong?
    If you understand what you're doing, you're not learning anything.

  3. #3
    Obsessed with C chrismiceli's Avatar
    Join Date
    Jan 2003
    Posts
    501
    Well, it was expanding to be quite long. x, y, z are all really members of structs and expanding each one took multiple lines. I was just wondering, I can work with no other solution, just curious. Thanks.
    Help populate a c/c++ help irc channel
    server: irc://irc.efnet.net
    channel: #c

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Well...you could try (for integer types):
    Code:
    if((x+y+z)/3 == x && a != x)
    {
      // code
    }
    At least, I think that should work...as long as there's no overflow problem. I guess it isn't much shorter...
    If you understand what you're doing, you're not learning anything.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by itsme86
    Well...you could try (for integer types):
    Code:
    if((x+y+z)/3 == x && a != x)
    {
      // code
    }
    At least, I think that should work...as long as there's no overflow problem. I guess it isn't much shorter...
    It definately would not work:
    Code:
    int x, y, z, a;
    
    x = 4;
    y = 3;
    z = 5;
    a = whatever;
    
    if( ( x + y + z ) / 3 == x && a != x; )
    {
        printf("In this case, the average of x + y + z == x, but they do not equal eachother.\n");
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    The minimum you're going to get is three checks. How you do those is up to you:
    Code:
    if( !(z-y) && !(y-x) && (z-a) )
    That should be fun. You again have the possibility of signed undeflow though with the last check.

    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Good point...
    If you understand what you're doing, you're not learning anything.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Try this
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    void foo ( int x, int y, int z, int a ) {
        if ( x == y && y == z && x != a ) {
            printf( "foo yes %d %d %d %d\n", x, y, z, a );
        }
    }
    void bar ( int x, int y, int z, int a ) {
        if ( ( x + y + z ) / 3 == x && x != a ) {
            printf( "bar yes %d %d %d %d\n", x, y, z, a );
        }
    }
    void baz ( int x, int y, int z, int a ) {
        if ( (x & y & z) == x && (x | y | z) == x && x != a ) {
            printf( "baz yes %d %d %d %d\n", x, y, z, a );
        }
    }
    
    int main( void ) {
        void (*fn[])(int,int,int,int) = { foo, bar, baz };
        int i;
        for ( i = 0 ; i < 3 ; i++ ) fn[i]( 2,1,3,4 );
        for ( i = 0 ; i < 3 ; i++ ) fn[i]( 1,3,2,4 );
        for ( i = 0 ; i < 3 ; i++ ) fn[i]( 1,1,1,2 );
        for ( i = 0 ; i < 3 ; i++ ) fn[i]( 1,3,1,2 );
        return 0;
    }
    You can combine many values together using & and |, and then only perform a pair of tests
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Then couldn't you just do:
    Code:
    if( (x & y & z) == (x | y | z) && x != a )
    But I wouldn't have stumbled across that without your post.

    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    <burns>excellent</burns>
    Now it looks like it takes a lot more explaining than actually doing it
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I believe the OP wanted to do the check by writing the variables fewer times, not by actually doing fewer comparisons...
    If you understand what you're doing, you're not learning anything.

  12. #12
    Registered User
    Join Date
    Jun 2004
    Posts
    84
    Quote Originally Posted by chrismiceli
    Well, it was expanding to be quite long. x, y, z are all really members of structs and expanding each one took multiple lines. I was just wondering, I can work with no other solution, just curious. Thanks.
    Well... if your structures are _that_ long and you don't like writing, you can put values in temp vars and hope that compiler will optimize them away.
    Code:
    {
      int tempX = x;
      int tempY = y;
      int tempZ = z;
      if (tempX == tempY && tempY == tempZ && tempZ != a)
      {
        //code
      }
    }

  13. #13
    Registered User
    Join Date
    Apr 2004
    Posts
    210
    Quote Originally Posted by quzah
    Then couldn't you just do:
    Code:
     if( (x & y & z) == (x | y | z) && x != a )
    But I wouldn't have stumbled across that without your post.

    Quzah.
    afaik, true is defined as !false and false as 0. Assuming true is always 1 (which it is here, but I don't know if this is guaranteed), this should work:

    Code:
    if (((x == y) * z) == z && z != a)
    This could be written as...

    Code:
    if ((((x == y) * z) == z) * a != a)
    ... but this isn't shorter and only obfuscates stuff.

  14. #14
    Registered User
    Join Date
    Sep 2004
    Posts
    124
    There doesn't seem to be an easy way to achieve this. Another possibility is to create a little function:

    Code:
    int xtest(inx x, int y, int z, int a)
    {
    	return (x == y && x == z && x != a) ? TRUE : FALSE;
    }
    Then you only need specify each element for test once in your code.

    Or even use a macro.

  15. #15
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    won't this work?:

    Code:
     if(a == b == c == d) {
     //...
     }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 07-05-2010, 10:43 AM
  2. std::string comparison versus int comparison
    By leeor_net in forum C++ Programming
    Replies: 3
    Last Post: 04-12-2009, 07:28 AM
  3. Bug in iterator comparison in C++ standard?
    By steev in forum C++ Programming
    Replies: 14
    Last Post: 07-12-2008, 12:02 AM
  4. Binary comparison
    By tao in forum Windows Programming
    Replies: 0
    Last Post: 06-28-2006, 12:10 PM
  5. comparison between pointer and integer
    By bazzano in forum C Programming
    Replies: 3
    Last Post: 03-07-2006, 01:15 PM