Thread: Ternary operator

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    32

    Ternary operator

    Hello,

    I have a silly question:

    Why do programmers use the ternary operator as shown in the abs2 function with the extra pair of brackets enclosing the conditional statement? To improve readability? As far as I know the < operator has higher precedence so the code in abs1 below is perfectly valid.

    Code:
    int abs1(int a)
    {
       return (a < 0 ? -a : a);
    }
    
    int abs2(int a)
    {
       return ((a < 0) ? -a : a);
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by kkk
    Why do programmers use the ternary operator as shown in the abs2 function with the extra pair of brackets enclosing the conditional statement? To improve readability? As far as I know the < operator has higher precedence so the code in abs1 below is perfectly valid.
    Perhaps they simply do not remember with absolute certainly what the relevant precedence rules are. Case in point: why did you use the return statement with the extra pair of parentheses for abs1? After all, the code in abs3 below is perfectly valid:
    Code:
    int abs3(int a)
    {
        return a < 0 ? -a : a;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    This may also be a good time to point out that this function returns the wrong result for the most negative integer in a two's complement system.
    It would probably be best to make the return type unsigned.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by iMalc View Post
    This may also be a good time to point out that this function returns the wrong result for the most negative integer in a two's complement system.
    It would probably be best to make the return type unsigned.
    What on earth for?
    Code:
    #include<stdio.h>
    int main( void )
    {
        signed int x = -5;
        printf( "%u\n", (unsigned int) x );
        return 0;
    }
    Oops!

    Also, if subtracting a negative doesn't give you a positive, then your compiler fails at math.


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

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    As a matter of interest, C and C++ have some slight differences in precedence and treat the conditional operator differently. For this example, it is clearly not the case, but code written for compatibility with C and C++ will often have an extra set of parentheses in one or more of the expressions.

    Soma

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by quzah View Post
    What on earth for?
    As I said, it's for this:
    Code:
    abs(-2147483648);
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by iMalc View Post
    As I said, it's for this:
    I guess I'm missing something in your explanation, because changing the type of -5 to unsigned doesn't make it 5.


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

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by iMalc
    As I said, it's for this:
    Unfortunately, changing the return type to unsigned int will not fix the problem since the correct return value for abs(-2147483648) is 2147483648, but with two's complement INT_MAX in your example is presumably 2147483647.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Why don't you two try to take in all he said instead of just any one part.

    In most "Two's Complement" machinery, -2147483648 has the same binary representation as 2147483648 when the binary is treated as a positive integer value. Furthermore negating -2147483648, if it is the largest negative value, result in the same -2147483648 value. This is a well known issue.

    I guess I'm missing something in your explanation, because changing the type of -5 to unsigned doesn't make it 5.
    He didn't say to drop the act of negation. That makes your casting of "-5" example ridiculous. He said to change the return type so that it is large enough to represent the absolute value of the largest associated negative value as handled in most "Two's Complement" machinery.

    Unfortunately, changing the return type to unsigned int will not fix the problem since the correct return value for abs(-2147483648) is 2147483648, but with two's complement INT_MAX in your example is presumably 2147483647.
    Your logic is also flawed. The `INT_MAX' value probably is 2147483647, but you'd be needing to think about `UINT_MAX' where the value is 4294967295.

    Soma

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by phantomotap
    you'd be needing to think about `UINT_MAX' where the value is 4294967295.
    Oh yeah, in that case iMalc's suggestion works.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by laserlight View Post
    Oh yeah, in that case iMalc's suggestion works.
    So then what happens when you cast it back to signed when your function returns the value? Because we weren't talking about unsigned values here.
    Code:
    signed char c = -128;
    c = abs( c );
    If we were, we wouldn't need an abs function. Wikipedia:
    0 1 1 1 1 1 1 1 = 127
    0 1 1 1 1 1 1 0 = 126
    0 0 0 0 0 0 1 0 = 2
    0 0 0 0 0 0 0 1 = 1
    0 0 0 0 0 0 0 0 = 0
    1 1 1 1 1 1 1 1 = −1
    1 1 1 1 1 1 1 0 = −2
    1 0 0 0 0 0 0 1 = −127
    1 0 0 0 0 0 0 0 = −128
    Ok, so you make that signed -128 to 128, and then it's assigned right back to a signed char. Wouldn't that just turn it right back into signed -128?


    I can't seem to wrap my head around this one.

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

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by quzah
    So then what happens when you cast it back to signed when your function returns the value? Because we weren't talking about unsigned values here.
    I think that is fine though for this edge case: for a signed destination type, if the return type is signed, it is problematic; otherwise, it is still problematic. But if the destination type is unsigned, and if the return type is unsigned, it is not problematic, so at least there's a win there.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Practically, assuming a binary representation, signed integral types (signed char, short, int, long) have a property that they are asymmetric (i.e. XXX_MIN is not equal to -XXX_MAX for XXX corresponding to each of the signed integral types). The standard neither encourages nor discourages this, because it only specifies bounds on what those XXX_MIN and XXX_MAX values may have and, for each type, those values have the same magnitude. For example, it specifies (a little indirectly) that both INT_MIN and INT_MAX must both have a magnitude at least 32767. It does not require that INT_MIN be equal to -INT_MAX.

    If INT_MIN is not equal (mathematically) to -INT_MAX, then there is one value (one of those two extrema) for which multiplying by -1 gives undefined behaviour if the result is required to be stored in a value of the same type. So, if x is of type int with value -32768, INT_MIN has the value -32768, INT_MAX has the value 32767 then computing -x gives undefined behaviour if the result is to be stored in a variable of type int. In practice, depending on the underlying representation, that "undefined behaviour" might wrap around (for example, -INT_MIN may give the value INT_MIN), but there is nothing in the standard preventing some other type of behaviour (such as reporting an integer overflow).

    The result is, however, always defined if the result of computing -x is to be stored in an unsigned variable. All operations on unsigned integral types are described mathematically in terms of modulo arithmetic (for example, adding 1 to UINT_MAX will yield zero, converting -1 to unsigned will yield UINT_MAX). One cute side effect is that
    Code:
    unsigned abs4(int a)
    {
          return a < 0 ? -a : a;
    }
    will always yield correct results (unless its return value is converted back to int) but
    Code:
    int abs3(int a)
    {
          return a < 0 ? -a : a;
    }
    may exhibit undefined behaviour for some (edge case) values.
    Last edited by grumpy; 07-03-2011 at 11:37 PM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Ternary Operator to choose which operator to use
    By cncool in forum C Programming
    Replies: 7
    Last Post: 06-27-2011, 01:35 PM
  2. bug in ternary operator ?:
    By wiglaf in forum C Programming
    Replies: 14
    Last Post: 03-31-2011, 10:26 PM
  3. Is the PHP ternary operator broken?
    By mike_g in forum Tech Board
    Replies: 13
    Last Post: 07-18-2009, 05:04 PM
  4. Ternary operator expression
    By rits in forum C Programming
    Replies: 9
    Last Post: 03-13-2009, 08:02 AM
  5. ternary operator
    By abhijith gopal in forum C Programming
    Replies: 37
    Last Post: 07-10-2006, 11:58 AM