one's complement of unsigned char

Discussion in 'C Programming' started by subramanian, Dec 29, 2006.

  1. subramanian

    subramanian Guest

    Suppose I have the following statement:

    unsigned char x = 0;

    If I do,

    printf("%u\", ~x);

    it prints the value of UINT_MAX. I am using Intel machine. This same
    result is printed in both VC++ and gcc.

    In the second edition of K&R, section A7.4.6 in page 204 says the
    following:
    "If the operand is unsigned, the result is computed by subracting the
    value from the largest value of the promoted type".

    Does it mean that since the operand is unsigned, the promoted type is
    also unsigned.
    subramanian, Dec 29, 2006
    #1
    1. Advertising

  2. subramanian

    Zara Guest

    On 28 Dec 2006 21:09:42 -0800, "subramanian"
    <> wrote:

    >Suppose I have the following statement:
    >
    >unsigned char x = 0;
    >
    >If I do,
    >
    >printf("%u\", ~x);
    >
    >it prints the value of UINT_MAX. I am using Intel machine. This same
    >result is printed in both VC++ and gcc.
    >
    >In the second edition of K&R, section A7.4.6 in page 204 says the
    >following:
    >"If the operand is unsigned, the result is computed by subracting the
    >value from the largest value of the promoted type".
    >
    >Does it mean that since the operand is unsigned, the promoted type is
    >also unsigned.



    x is promoted to unsigned int before applying operator ~. Thus the
    result is the one's complement of 0u.

    To print the unsigned char that is the one's complement of x, you
    should use:

    printf("%u\", (unsigned char)(~x));

    That, is you should demote it before printing

    Zara
    Zara, Dec 29, 2006
    #2
    1. Advertising

  3. Zara wrote:
    > On 28 Dec 2006 21:09:42 -0800, "subramanian"
    > <> wrote:
    >
    > >Suppose I have the following statement:
    > >
    > >unsigned char x = 0;
    > >
    > >If I do,
    > >
    > >printf("%u\", ~x);
    > >
    > >it prints the value of UINT_MAX. I am using Intel machine. This same
    > >result is printed in both VC++ and gcc.
    > >
    > >In the second edition of K&R, section A7.4.6 in page 204 says the
    > >following:
    > >"If the operand is unsigned, the result is computed by subracting the
    > >value from the largest value of the promoted type".
    > >
    > >Does it mean that since the operand is unsigned, the promoted type is
    > >also unsigned.

    >
    >
    > x is promoted to unsigned int before applying operator ~.


    No, x is promoted to /signed/ int. It is only promoted to unsigned int
    if UCHAR_MAX > INT_MAX, which is not the case on any machine capable of
    running VC++ I'm aware of.

    > Thus the
    > result is the one's complement of 0u.


    The ~ operator returns the bitwise complement of its operand. One's
    complement refers to a particular representation of integers. (I know
    you just copied it from the original message.)

    > To print the unsigned char that is the one's complement of x, you
    > should use:
    >
    > printf("%u\", (unsigned char)(~x));
    >
    > That, is you should demote it before printing


    There is a possibility that ~0 is a trap representation. In this case,
    it is better to print (unsigned char) ~(unsigned int) x instead, which
    is guaranteed to be safe.
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Dec 29, 2006
    #3
  4. subramanian

    Zara Guest

    On 28 Dec 2006 22:29:19 -0800, "Harald van D?k" <>
    wrote:

    >Zara wrote:
    >> On 28 Dec 2006 21:09:42 -0800, "subramanian"
    >> <> wrote:
    >>
    >> >Suppose I have the following statement:
    >> >
    >> >unsigned char x = 0;
    >> >
    >> >If I do,
    >> >
    >> >printf("%u\", ~x);

    <...>
    >>
    >> x is promoted to unsigned int before applying operator ~.

    >
    >No, x is promoted to /signed/ int. It is only promoted to unsigned int
    >if UCHAR_MAX > INT_MAX, which is not the case on any machine capable of
    >running VC++ I'm aware of.


    Yes, of course, you are right. (STD C-> 6.3.1.1, 2)

    >
    >> Thus the
    >> result is the one's complement of 0u.

    >
    >The ~ operator returns the bitwise complement of its operand. One's
    >complement refers to a particular representation of integers. (I know
    >you just copied it from the original message.)


    You are right again.
    >
    >> To print the unsigned char that is the one's complement of x, you
    >> should use:
    >>
    >> printf("%u\", (unsigned char)(~x));
    >>
    >> That, is you should demote it before printing

    >
    >There is a possibility that ~0 is a trap representation. In this case,
    >it is better to print (unsigned char) ~(unsigned int) x instead, which
    >is guaranteed to be safe.


    Right again. Anyway, I would prefer to write

    (unsigned char) (~(unsigned int) x)

    Best regards,

    zara
    Zara, Dec 29, 2006
    #4
  5. subramanian

    Jack Klein Guest

    On Fri, 29 Dec 2006 06:43:33 +0100, Zara <>
    wrote in comp.lang.c:

    > On 28 Dec 2006 21:09:42 -0800, "subramanian"
    > <> wrote:
    >
    > >Suppose I have the following statement:
    > >
    > >unsigned char x = 0;
    > >
    > >If I do,
    > >
    > >printf("%u\", ~x);
    > >
    > >it prints the value of UINT_MAX. I am using Intel machine. This same
    > >result is printed in both VC++ and gcc.
    > >
    > >In the second edition of K&R, section A7.4.6 in page 204 says the
    > >following:
    > >"If the operand is unsigned, the result is computed by subracting the
    > >value from the largest value of the promoted type".
    > >
    > >Does it mean that since the operand is unsigned, the promoted type is
    > >also unsigned.

    >
    >
    > x is promoted to unsigned int before applying operator ~. Thus the
    > result is the one's complement of 0u.


    That is quite incorrect. 'x' is promoted to signed int, since signed
    into on this platform can hold all values of unsigned char.

    --
    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.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Dec 30, 2006
    #5
  6. subramanian

    subramanian Guest

    unsigned char x = 0;
    What is the behaviour of ~x according to the C standard.

    After reading K & R, I thought the variable will be promoted to signed
    int. Taking bitwise complement should give INT_MAX. But it does not
    happen here. I get UINT_MAX.

    Can someone clarify my doubt ?
    subramanian, Dec 30, 2006
    #6
  7. subramanian wrote:
    > unsigned char x = 0;
    > What is the behaviour of ~x according to the C standard.


    Strictly speaking it is undefined on the virtual C machine.

    >
    > After reading K & R, I thought the variable will be promoted to signed
    > int.


    An unsigned char will be promoted to int if an int can hold all the
    values
    of unsigned char, otherwise it will be promoted to unsigned int. On
    hosted implementations, it will promote to int.

    > Taking bitwise complement should give INT_MAX.


    No, taking the bitwise complement of all bits zero yields all bits one.
    There
    are three different possible representations for signed integers,[1]
    two's
    complement, ones' complement and sign-magnitude. The value yielded is
    different for each form of representation. Indeed, the 'value' may be a
    trap
    representation on a ones' complement machine.

    [1] Unlike C99, C90 does not specify those representations explicitly,
    though Committee members have commented that documents from the
    'Normative References' component of C90 imply that those 3 options
    are the only ones available to a C90 implementation.

    > But it does not happen here. I get UINT_MAX.


    You snipped the bit of code you used to get that value. You previously
    wrote...

    printf("%u\", ~x);

    Though what you probably meant to post was...

    printf("%u\n", ~x);

    That code invokes undefined behaviour because %u expects an unsigned
    int and you supply a value of type int that is not representable as an
    unsigned int (on a 2c machine.)[2]

    Try...

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

    This will yield -1 on a 2c machine.

    All that said, bitwise operations should generally only be performed on
    unsigned integer types of rank equal or higher than unsigned int. Why?
    To avoid the sorts of issues of undefined behaviour that you've
    encountered.

    [2] Strictly speaking, passing an int for %u invokes undefined
    behaviour
    even if int value is non-negative.

    >
    > Can someone clarify my doubt ?


    Read the texts very carefully. When working on character types, and
    especially when working on bitwise operators, be very careful about
    implicit promotions (e.g. integral promotions, usual arithmetic
    promotions,
    etc...).

    --
    Peter
    Peter Nilsson, Dec 30, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mantorok Redgormor

    sign magnitude, ones complement, two's complement

    Mantorok Redgormor, Oct 5, 2003, in forum: C Programming
    Replies:
    8
    Views:
    8,597
    Glen Herrmannsfeldt
    Oct 8, 2003
  2. Complement of unsigned char

    , Mar 29, 2006, in forum: C Programming
    Replies:
    7
    Views:
    316
    Keith Thompson
    Mar 29, 2006
  3. sarathy

    1's complement and 2's complement

    sarathy, Aug 1, 2006, in forum: C Programming
    Replies:
    20
    Views:
    2,187
    Bo Persson
    Aug 2, 2006
  4. sarathy
    Replies:
    22
    Views:
    2,346
    Bo Persson
    Aug 2, 2006
  5. Roberto Waltman

    2's complement vs. 1's complement vs. ...

    Roberto Waltman, Jun 9, 2011, in forum: C Programming
    Replies:
    4
    Views:
    1,353
    Michael Press
    Jun 14, 2011
Loading...

Share This Page