Thread: Signed integer conversion

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Signed integer conversion

    I have already bought the C11 Standard and am still studying the document, getting a feel for its structure, organization and language. So I'm still struggling a bit to feel confident about some answers to my questions.

    One of them pertains to integer implicit conversion and the role it plays on an expression of this kind. In particular, I can't fully decide if the following code is defined or undefined from reading the Standard text below.

    Code:
    long n = LONG_MIN;
    unsigned long m = -n;
    6.3.1.3(2)
    Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

    6.5.3.3(3)
    The result of the unary - operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.
    I understand the promotion takes place before the unary minus sign is applied. So the very first operation is m promotion to ulong. But I can't then reconcile that with the text on 6.3.1.3 and what happens next when the unary minus sign brings the result back to a negative value outside m range.
    Last edited by Mario F.; 10-23-2016 at 09:36 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Mario F.
    I understand the promotion takes place before the unary minus sign is applied.
    True, but the integer promotions only promote to int or unsigned int (see clause 6.3.1.1 paragraph 2), so they have no effect here since the types involved are long and unsigned long. My interpretation is that, assuming two's complement, because the result of -n is outside of the range of long, the behaviour is undefined as per clause 6.5 paragraph 5, though in practice the effect will probably be equivalent to:
    Code:
    long n = LONG_MIN;
    unsigned long m = n;
    m = -m;
    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
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by laserlight View Post
    True, but the integer promotions only promote to int or unsigned int (see clause 6.3.1.1 paragraph 2),
    Do you mean paragraph 4? "The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any"
    But I see perfectly what you mean; there's no promotion since they have the same rank.

    Quote Originally Posted by laserlight View Post
    Though in practice the effect will probably be equivalent to:
    Code:
    long n = LONG_MIN;
    unsigned long m = n;
    m = -m;
    GCC 5.4 seems to produces something like (because it does result in the absolute value on LONG_MIN):

    Code:
    long n = LONG_MIN;
    unsigned long m = LONG_MAX + 1UL;
    LONG_MAX + 1UL is suspiciously similar to 6.3.1.3(p. 2). So the operation in fact is very likely well defined, now that you demonstrated that 6.5.3.3(p. 3) doesn't apply, and as such 6.3.1.3 has full force. Do you agree?

    ---

    EDIT: Nope! I'm not making any sense. With that reasoning I'm ignoring the unary minus sign that is also part of the expression. You are right. It must be undefined.

    So to do a correct arithmetic conversion of any signed integer type T to its unsigned representation UT, must be:

    Code:
    if (T == T_MIN)
        UT = T_MAX + (UT) 1;
    else if (T < 0)
        UT = -T;
    else
        UT = T;
    Last edited by Mario F.; 10-23-2016 at 01:03 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Mario F.
    Do you mean paragraph 4? "The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any"
    No, that is a bullet point under paragraph 1. I mean the entire paragraph 2:
    Quote Originally Posted by C11 Clause 6.3.11 Paragraph 2
    The following may be used in an expression wherever an int or unsigned int may be used:
    • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
    • A bit-field of type _Bool, int, signed int, or unsigned int.

    If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.
    Quote Originally Posted by Mario F.
    But I see perfectly what you mean; there's no promotion since they have the same rank.
    No, there is no promotion since the operand of unary - is of type long. Even if it were of type int (with the destination type of the assignment being of type unsigned long) there would be no promotion as per Clause 6.3.11. What you might be thinking of are the usual arithmetic conversions, but I don't think those apply here since we're dealing with unary - so there is only one operand rather two for which a common type needs to be determined. The usual arithmetic conversions are not applied in simple assignment, as is the case here, since the right hand operand is just converted to the type of the left hand operand, i.e., the long value is converted to unsigned long, or in my example of int, the int value that is the result of the unary - operation would be converted to unsigned long without this conversion being an "integer promotion".

    Quote Originally Posted by Mario F.
    So to do a correct arithmetic conversion of any signed integer type T to its unsigned representation UT, must be:
    Rather than "unsigned representation", it looks like you're implementing an absolute value function whose parameter is of type T and return value is of corresponding type UT.
    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

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Good grief. There's a still a large gap between my current position and a better understanding. Thanks laserlight. I'll digest this information more carefully next time.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Signed and Unsigned Integer Calculation
    By KansaiRobot in forum C Programming
    Replies: 5
    Last Post: 12-07-2015, 11:39 PM
  2. Replies: 19
    Last Post: 09-25-2014, 10:02 PM
  3. Signed hex conversion
    By james123 in forum C Programming
    Replies: 2
    Last Post: 05-11-2010, 08:06 PM
  4. Compiler Error: Unsigned vs Signed Integer Expression
    By ChristianTool in forum C++ Programming
    Replies: 6
    Last Post: 05-05-2005, 04:57 PM
  5. Very large signed integer math question
    By Criz in forum C Programming
    Replies: 8
    Last Post: 12-01-2002, 12:43 PM

Tags for this Thread