unsigned char

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

    #1

    unsigned char

    I tried a simple program as follows:

    int main(void) {
    unsigned char x = 129;
    signed char y = 127;

    printf("~x = %d\n", ~x);
    printf("~y = %d\n", ~y);

    return 0;
    }

    it printed out:

    ~x = -130
    ~y = -128

    Since x is an one-byte unsigned char and its range should be [-127,
    +127], is it because that x was first promoted to int and then ~x got
    evaluated to -130 in 2's complement? Thanks for any hints. Is it true
    that all chars (char, unsigned char and signed char) would be promoted
    to int when getting involved in computation?

    ~xg

  • Clark S. Cox III

    #2
    Re: unsigned char

    FlyingBird wrote:
    I tried a simple program as follows:
    >
    int main(void) {
    unsigned char x = 129;
    signed char y = 127;
    >
    printf("~x = %d\n", ~x);
    printf("~y = %d\n", ~y);
    >
    return 0;
    }
    >
    it printed out:
    >
    ~x = -130
    ~y = -128
    >
    Since x is an one-byte unsigned char and its range should be [-127,
    +127], is it because that x was first promoted to int and then ~x got
    evaluated to -130 in 2's complement?
    Yes, the signed char was promoted in exactly the same way.
    Thanks for any hints. Is it true
    that all chars (char, unsigned char and signed char) would be promoted
    to int when getting involved in computation?
    Yes, as would both shorts (unsigned short int and signed short int).


    --
    Clark S. Cox III
    clarkcox3@gmail .com

    Comment

    • Bill Medland

      #3
      Re: unsigned char

      FlyingBird wrote:
      I tried a simple program as follows:
      >
      int main(void) {
      unsigned char x = 129;
      signed char y = 127;
      >
      printf("~x = %d\n", ~x);
      printf("~y = %d\n", ~y);
      >
      return 0;
      }
      >
      it printed out:
      >
      ~x = -130
      ~y = -128
      >
      Since x is an one-byte unsigned char and its range should be [-127,
      +127], is it because that x was first promoted to int and then ~x got
      evaluated to -130 in 2's complement? Thanks for any hints. Is it true
      that all chars (char, unsigned char and signed char) would be promoted
      to int when getting involved in computation?
      >
      ~xg
      %d means signed int. You told printf to interpret the argument as a signed
      integer. Luckily it was interpretable as one.

      --
      Bill Medland

      Comment

      • cassius

        #4
        Re: unsigned char

        FlyingBird wrote:
        Since x is an one-byte unsigned char and its range should be [-127,
        +127], is it because that x was first promoted to int and then ~x got
        evaluated to -130 in 2's complement? ...
        x = 129 = 0x81. The bitwise complement (~) will change all bits, so
        ~x=0x7E = 126. However, at the printf, the parameter is being casted
        to an integer value. So, the the ~x is yielding, in fact, 0xFF7e
        (assuming your int is 16-bits).

        As the last most significant bit is set, The printf will interpret it
        as a negative number, and put the (-) sign. 0xFF7E will be
        complemented, yielding 0x0081, and will have one added, 0x0082 = 130.

        The same goes with y.

        I am not sure why result of ~x is interpreted as an integer. But if you
        use changes the following line:

        x=~x;
        y=~y;

        printf("~x = %d\n", x);
        printf("~y = %d\n", y);

        the output changes to 126 and -128.

        Comment

        • Eric Sosman

          #5
          Re: unsigned char



          Bill Medland wrote On 10/24/06 16:53,:
          FlyingBird wrote:
          >
          >
          >>I tried a simple program as follows:
          >>
          >>int main(void) {
          > unsigned char x = 129;
          > signed char y = 127;
          >>
          > printf("~x = %d\n", ~x);
          > printf("~y = %d\n", ~y);
          >>
          > return 0;
          >>}
          >>
          >>it printed out:
          >>
          >>~x = -130
          >>~y = -128
          >>
          >>Since x is an one-byte unsigned char and its range should be [-127,
          >>+127], is it because that x was first promoted to int and then ~x got
          >>evaluated to -130 in 2's complement? Thanks for any hints. Is it true
          >>that all chars (char, unsigned char and signed char) would be promoted
          >>to int when getting involved in computation?
          >>
          >>~xg
          >
          %d means signed int. You told printf to interpret the argument as a signed
          integer. Luckily it was interpretable as one.
          s/interpretable as//

          The expression `~y' *is* a signed int on all machines,
          and `~x' *is* a signed int except on "exotic" machines where
          UCHAR_MAX INT_MAX.

          --
          Eric.Sosman@sun .com

          Comment

          • Bill Medland

            #6
            Re: unsigned char

            Eric Sosman wrote:
            >
            >
            Bill Medland wrote On 10/24/06 16:53,:
            >FlyingBird wrote:
            >>
            >>
            >>>I tried a simple program as follows:
            >>>
            >>>int main(void) {
            >> unsigned char x = 129;
            >> signed char y = 127;
            >>>
            >> printf("~x = %d\n", ~x);
            >> printf("~y = %d\n", ~y);
            >>>
            >> return 0;
            >>>}
            >>>
            >>>it printed out:
            >>>
            >>>~x = -130
            >>>~y = -128
            >>>
            >>>Since x is an one-byte unsigned char and its range should be [-127,
            >>>+127], is it because that x was first promoted to int and then ~x got
            >>>evaluated to -130 in 2's complement? Thanks for any hints. Is it true
            >>>that all chars (char, unsigned char and signed char) would be promoted
            >>>to int when getting involved in computation?
            >>>
            >>>~xg
            >>
            >%d means signed int. You told printf to interpret the argument as a
            >signed
            >integer. Luckily it was interpretable as one.
            >
            s/interpretable as//
            >
            The expression `~y' *is* a signed int on all machines,
            and `~x' *is* a signed int except on "exotic" machines where
            UCHAR_MAX INT_MAX.
            >
            Yes, and there are a load of other things that can be interpreted as a
            signed int such as a signed long on a machine with a 16 bit int LSB and a
            long long on a 32 bit LSB machine, but not a float or a pointer. You and I
            know what happens if the printf format doesn't match the arguments passed
            to a varargs but I'll bet the OP doesn't.
            --
            Bill Medland

            Comment

            • Frederick Gotham

              #7
              Re: unsigned char

              FlyingBird posted:
              I tried a simple program as follows:
              >
              int main(void) {
              unsigned char x = 129;
              signed char y = 127;
              >
              printf("~x = %d\n", ~x);

              Due to integer promotion, the following expression:

              ~x

              either becomes:

              ~(int)x

              or:

              ~(unsigned)x

              depending on whether the following evaluates to true:

              UCHAR_MAX INT_MAX

              --

              Frederick Gotham

              Comment

              • Eric Sosman

                #8
                Re: unsigned char



                Bill Medland wrote On 10/24/06 17:43,:
                Eric Sosman wrote:
                >
                >
                >>
                >>Bill Medland wrote On 10/24/06 16:53,:
                >>
                >>>FlyingBird wrote:
                >>>
                >>>
                >>>
                >>>>I tried a simple program as follows:
                >>>>
                >>>>int main(void) {
                >>>unsigned char x = 129;
                >>>signed char y = 127;
                >>>>
                >>>printf("~x = %d\n", ~x);
                >>>printf("~y = %d\n", ~y);
                >>>>
                >>>return 0;
                >>>>}
                >>>>
                >>>>it printed out:
                >>>>
                >>>>~x = -130
                >>>>~y = -128
                >>>>
                >>>>Since x is an one-byte unsigned char and its range should be [-127,
                >>>>+127], is it because that x was first promoted to int and then ~x got
                >>>>evaluated to -130 in 2's complement? Thanks for any hints. Is it true
                >>>>that all chars (char, unsigned char and signed char) would be promoted
                >>>>to int when getting involved in computation?
                >>>>
                >>>>~xg
                >>>
                >>>%d means signed int. You told printf to interpret the argument as a
                >>>signed
                >>>integer. Luckily it was interpretable as one.
                >>
                > s/interpretable as//
                >>
                > The expression `~y' *is* a signed int on all machines,
                >>and `~x' *is* a signed int except on "exotic" machines where
                >>UCHAR_MAX INT_MAX.
                >>
                >
                Yes, and there are a load of other things that can be interpreted as a
                signed int such as a signed long on a machine with a 16 bit int LSB and a
                long long on a 32 bit LSB machine, but not a float or a pointer. You and I
                know what happens if the printf format doesn't match the arguments passed
                to a varargs but I'll bet the OP doesn't.
                There's no mismatch in the posted code, except possibly
                if UCHAR_MAX INT_MAX. In particular, there is no mismatch
                if CHAR_BIT == 8.

                I think you're overlooking the effect of the arithmetic
                promotions (which is what the O.P. was asking about, so he may
                not be quite as wet behind the ears as you suppose).

                --
                Eric.Sosman@sun .com

                Comment

                • Clark S. Cox III

                  #9
                  Re: unsigned char

                  Bill Medland wrote:
                  FlyingBird wrote:
                  >
                  >I tried a simple program as follows:
                  >>
                  >int main(void) {
                  > unsigned char x = 129;
                  > signed char y = 127;
                  >>
                  > printf("~x = %d\n", ~x);
                  > printf("~y = %d\n", ~y);
                  >>
                  > return 0;
                  >}
                  >>
                  >it printed out:
                  >>
                  >~x = -130
                  >~y = -128
                  >>
                  >Since x is an one-byte unsigned char and its range should be [-127,
                  >+127], is it because that x was first promoted to int and then ~x got
                  >evaluated to -130 in 2's complement? Thanks for any hints. Is it true
                  >that all chars (char, unsigned char and signed char) would be promoted
                  >to int when getting involved in computation?
                  >>
                  >~xg
                  %d means signed int. You told printf to interpret the argument as a signed
                  integer.
                  Yes, he/she told printf to expect a signed int, and then gave it a
                  signed int. Where's the problem?

                  Luckily it was interpretable as one.
                  >
                  It wasn't just interpretable as a signed int, it *was* a signed int.

                  Unless (unsigned char) can hold larger values than (int), ~x and ~y will
                  *always* be (int).

                  --
                  Clark S. Cox III
                  clarkcox3@gmail .com

                  Comment

                  • Jack Klein

                    #10
                    Re: unsigned char

                    On 24 Oct 2006 12:47:32 -0700, "FlyingBird " <gaoxingbo@gmai l.com>
                    wrote in comp.lang.c:
                    I tried a simple program as follows:
                    >
                    int main(void) {
                    unsigned char x = 129;
                    signed char y = 127;
                    >
                    printf("~x = %d\n", ~x);
                    printf("~y = %d\n", ~y);
                    >
                    return 0;
                    }
                    >
                    it printed out:
                    >
                    ~x = -130
                    ~y = -128
                    >
                    Since x is an one-byte unsigned char and its range should be [-127,
                    +127],
                    That's quite wrong. An unsigned char can never have a value of -127,
                    or -1, or any other negative value. The minimum value of an unsigned
                    char, or any other unsigned integer type, is 0. Always has been and
                    always will be.

                    The maximum value for an unsigned char must be at least 255.

                    --
                    Jack Klein
                    Home: http://JK-Technology.Com
                    FAQs for
                    comp.lang.c http://c-faq.com/
                    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
                    alt.comp.lang.l earn.c-c++

                    Comment

                    • CBFalconer

                      #11
                      Re: unsigned char

                      Jack Klein wrote:
                      "FlyingBird " <gaoxingbo@gmai l.comwrote in comp.lang.c:
                      >
                      >I tried a simple program as follows:
                      >>
                      >int main(void) {
                      > unsigned char x = 129;
                      > signed char y = 127;
                      >>
                      > printf("~x = %d\n", ~x);
                      > printf("~y = %d\n", ~y);
                      > return 0;
                      >}
                      >>
                      >it printed out:
                      >>
                      >~x = -130
                      >~y = -128
                      >>
                      >Since x is an one-byte unsigned char and its range should be
                      >[-127, +127],
                      >
                      That's quite wrong. An unsigned char can never have a value of
                      -127, or -1, or any other negative value. The minimum value of
                      an unsigned char, or any other unsigned integer type, is 0.
                      Always has been and always will be.
                      >
                      The maximum value for an unsigned char must be at least 255.
                      Yeah, but he told printf it was a signed integer. Bad.

                      --
                      Chuck F (cbfalconer at maineline dot net)
                      Available for consulting/temporary embedded and systems.
                      <http://cbfalconer.home .att.net>

                      Comment

                      • Harald van Dijk

                        #12
                        Re: unsigned char

                        CBFalconer wrote:
                        Jack Klein wrote:
                        "FlyingBird " <gaoxingbo@gmai l.comwrote in comp.lang.c:
                        I tried a simple program as follows:
                        >
                        int main(void) {
                        unsigned char x = 129;
                        signed char y = 127;
                        >
                        printf("~x = %d\n", ~x);
                        printf("~y = %d\n", ~y);
                        return 0;
                        }
                        >
                        it printed out:
                        >
                        ~x = -130
                        ~y = -128
                        >
                        Since x is an one-byte unsigned char and its range should be
                        [-127, +127],
                        That's quite wrong. An unsigned char can never have a value of
                        -127, or -1, or any other negative value. The minimum value of
                        an unsigned char, or any other unsigned integer type, is 0.
                        Always has been and always will be.

                        The maximum value for an unsigned char must be at least 255.
                        >
                        Yeah, but he told printf it was a signed integer. Bad.
                        As has been pointed out by others in this thread, what printf() gets
                        /is/ a signed integer. Even if unsigned char weren't promoted as the
                        operand of the ~ operator, the result of that would still be because of
                        the default argument promotions. I do not see what this has to do with
                        the specific message you replied to, though.

                        Comment

                        • Peter Nilsson

                          #13
                          Re: unsigned char

                          Clark S. Cox III wrote:
                          FlyingBird wrote:
                          I tried a simple program as follows:

                          int main(void) {
                          unsigned char x = 129;
                          signed char y = 127;

                          printf("~x = %d\n", ~x);
                          printf("~y = %d\n", ~y);

                          return 0;
                          }

                          it printed out:

                          ~x = -130
                          ~y = -128

                          Since x is an one-byte unsigned char and its range should be [-127,
                          +127],
                          No, the range of unsigned char is [0..UCHAR_MAX], where UCHAR_MAX
                          is one less than a power of 2, and is at least 255.
                          is it because that x was first promoted to int and then ~x got
                          evaluated to -130 in 2's complement?
                          >
                          Yes, the signed char was promoted in exactly the same way.
                          >
                          Thanks for any hints. Is it true
                          that all chars (char, unsigned char and signed char) would be
                          promoted to int when getting involved in computation?
                          >
                          Yes, as would both shorts (unsigned short int and signed short int).
                          No, unsigned short will promote to int iff USHRT_MAX <= INT_MAX,
                          otherwise it promotes to unsigned int. There are modern implementations
                          where unsigned short has the same size, range and representation as
                          unsigned int.

                          It is also possible for unsigned char to promote to unsigned int,
                          though
                          that is unlikely (if not impossible) on a hosted implementation [or a
                          freestanding implementation supporting <stdio.h>.]

                          --
                          Peter

                          Comment

                          • CBFalconer

                            #14
                            Re: unsigned char

                            Peter Nilsson wrote:
                            >
                            .... snip ...
                            >
                            No, unsigned short will promote to int iff USHRT_MAX <= INT_MAX,
                            otherwise it promotes to unsigned int. There are modern
                            implementations where unsigned short has the same size, range
                            and representation as unsigned int.
                            This fooferaw is due to the ridiculous decision of the standards
                            committee to preserve value, rather than unsignedness, in integral
                            promotions. Bites every time.

                            --
                            Chuck F (cbfalconer at maineline dot net)
                            Available for consulting/temporary embedded and systems.
                            <http://cbfalconer.home .att.net>


                            Comment

                            Working...