Unsigned & signed int

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kislay

    Unsigned & signed int

    Consider the following code snippet

    unsigned int i=10;
    int j= - 2; // minus 2
    if(i>j)
    cout<<"i is greater";
    else
    cout<<"j is greater";

    Since i is unsigned , j is greater . I know why , but vaguely . Can
    someone please explain the mechanics behind it . Is the unsigned int
    converted to signed or is it vice-versa . Also , the same rules would
    apply to char as well , right ?

  • Joachim Schmitz

    #2
    Re: Unsigned &amp; signed int

    "Kislay" <kislaychandra@ gmail.comschrie b im Newsbeitrag
    news:1191350059 .674272.186400@ 22g2000hsm.goog legroups.com...
    Consider the following code snippet
    >
    unsigned int i=10;
    int j= - 2; // minus 2
    if(i>j)
    cout<<"i is greater";
    else
    cout<<"j is greater";
    This is C++, not C, try comp.lang.c++. Or use printf() or puts().
    Also the else branch is wrong "j is greater or equal" would be the correct
    statement.
    Since i is unsigned , j is greater . I know why , but vaguely . Can
    someone please explain the mechanics behind it . Is the unsigned int
    converted to signed or is it vice-versa . Also , the same rules would
    apply to char as well , right ?
    in C, I think the signed int would get promoted to unsigned int. And yes,
    chars should do the same. That's why you get 'j is greater' (in C, not sure
    about C++)

    if((int)i>j)
    would give the correct/expected output.

    Strange, I'd have expected my compiler to give a warning about the implicit
    conversion ...


    Bye, Jojo


    Comment

    • Martin Wells

      #3
      Re: Unsigned &amp; signed int

      On Oct 2, 7:34 pm, Kislay <kislaychan...@ gmail.comwrote:
      Consider the following code snippet
      >
      unsigned int i=10;
      int j= - 2; // minus 2
      if(i>j)
      cout<<"i is greater";
      else
      cout<<"j is greater";
      >
      Since i is unsigned , j is greater . I know why , but vaguely . Can
      someone please explain the mechanics behind it . Is the unsigned int
      converted to signed or is it vice-versa . Also , the same rules would
      apply to char as well , right ?

      Rule 1: Things get promoted to SIGNED integer types where possible,
      otherwise UNSIGNED.

      Rule 2: The smaller of the two types involved in the operation has to
      change to the bigger type.

      Rule 3: If you're left with two types of the same size, but where one
      is signed and the other unsigned, they both become unsigned.

      Firstly, let's start with the types smaller than int. These types are
      as follows:

      signed char
      unsigned char
      signed short
      unsigned short

      The C Standard guarantees the following:
      CHAR_MAX <= SHRT_MAX <= INT_MAX <= LONG_MAX
      and also the following:
      UCHAR_MAX <= USHRT_MAX <= UINT_MAX <= ULONG_MAX

      Before you can do ANYTHING to any of the integer types smaller than
      int, they must be promoted. As mentioned before, they promote to
      SIGNED where possible, otherwise unsigned. Signed char and signed
      short will always promote to signed int on every implementation. As
      for unsigned char and unsigned short, they will promote to signed int
      on some system, but unsigned int on other systems, depending on
      whether all the values of the smaller type can be stored in signed
      int. After the promotion of the smaller type takes place, you could
      still be left with the following combinations:

      1: (unsigned int) + (signed int)
      2: (int) + (long)
      3: (unsigned int) + (long)
      4: (unsigned int) + (unsigned long)

      In number 1, both types are the same size but one of them is unsigned,
      so they both become unsigned.
      In number 2, the int has to become a long.
      In number 3, the int has to become a long, but we don't know if all
      the values of unsigned int can be stored in a signed long. Therefore,
      on some systems this will become an unsigned long, while on others it
      will become a signed long. Once the two types are either kind of long,
      they will become unsigned long if either of them is unsigned,
      otherwise they'll stay as signed long.
      In number 4, they'll both become unsigned long.

      I suppose the thought process is as follows:

      1: Promote things that are smaller than int.
      2: Match the sizes (but being careful about whether the small type
      will become signed or unsigned of the bigger type).
      3: Once the sizes are match, match the signs (if one of them is
      unsigned, then they both become unsigned).

      Now... as for the rules for converting from unsigned to signed... what
      you do is take the max value of the unsigned type, add 1 to it, and
      then add it to the signed value.

      So let's take -1. Let's pretend that UCHAR_MAX is 255. Therefore we
      add as follows:

      -1 + (255 + 1) = 255

      Therefore the following two are equivalent:

      char unsigned c = UCHAR_MAX;
      char unsigned c = -1;

      As are the following:

      short unsigned su = USHRT_MAX - 5;
      short unsigned su = -6;

      I'll edit your own original code to show you exactly what's going to
      happen:

      unsigned int i=10;

      int j= - 2; // minus 2

      unsigned j_changed_to_un signed = UINT_MAX - 1;

      if(i j_changed_to_un signed)
      cout<<"i is greater";
      else
      cout<<"j_change d_to_unsigned is greater";


      You might wanna use printf instead of cout on this newsgroup though ;)

      Martin


      Comment

      • Martin Wells

        #4
        Re: Unsigned &amp; signed int

        Now... as for the rules for converting from unsigned to signed...

        signed to unsigned

        Comment

        • Martin Ambuhl

          #5
          Re: Unsigned &amp; signed int

          Kislay wrote:
          Consider the following code snippet
          >
          unsigned int i=10;
          int j= - 2; // minus 2
          if(i>j)
          cout<<"i is greater";
          else
          cout<<"j is greater";
          Note that however cout is defined, and to use the "<<" operator on it is
          really ought to be an unsigned integral type, it makes no sense to shift
          it left by a string constant. And you probably want to lose the space
          between '-' and '2', as well as the silly comment.
          Since i is unsigned , j is greater . I know why , but vaguely . Can
          someone please explain the mechanics behind it . Is the unsigned int
          converted to signed or is it vice-versa . Also , the same rules would
          apply to char as well , right ?
          I believe the question you meant to ask is explicitly covered in the
          FAQ. See Question 3.19 "Q: What's the difference between the ``unsigned
          preserving'' and ``value preserving'' rules?" where, among other things,
          this code
          unsigned short us = 10;
          int i = -5;
          if(i us)
          printf("whoops! \n");
          is discussed.
          The question and answer can be found at
          <http://c-faq.com/expr/preservingrules .html>, but you really want to
          start trying to digest the FAQ as a whole <http://c-faq.com/index.html>.

          Comment

          • pete

            #6
            Re: Unsigned &amp; signed int

            Martin Wells wrote:
            The C Standard guarantees the following:
            CHAR_MAX <= SHRT_MAX <= INT_MAX <= LONG_MAX
            You misspelled "SCHAR_MAX" .

            --
            pete

            Comment

            • Old Wolf

              #7
              Re: Unsigned &amp; signed int

              On Oct 3, 10:46 am, Martin Wells <war...@eircom. netwrote:
              >
              char unsigned c = UCHAR_MAX;
              char unsigned c = -1;
              JKop, JKop, is that you?

              Comment

              Working...