By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,445 Members | 1,329 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,445 IT Pros & Developers. It's quick & easy.

one's complement of unsigned char

P: n/a
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.

Dec 29 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
On 28 Dec 2006 21:09:42 -0800, "subramanian"
<su**************@yahoo.comwrote:
>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
Dec 29 '06 #2

P: n/a
Zara wrote:
On 28 Dec 2006 21:09:42 -0800, "subramanian"
<su**************@yahoo.comwrote:
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.

Dec 29 '06 #3

P: n/a
On 28 Dec 2006 22:29:19 -0800, "Harald van D?k" <tr*****@gmail.com>
wrote:
>Zara wrote:
>On 28 Dec 2006 21:09:42 -0800, "subramanian"
<su**************@yahoo.comwrote:
>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
Dec 29 '06 #4

P: n/a
On Fri, 29 Dec 2006 06:43:33 +0100, Zara <me*****@dea.spamcon.org>
wrote in comp.lang.c:
On 28 Dec 2006 21:09:42 -0800, "subramanian"
<su**************@yahoo.comwrote:
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/~a...FAQ-acllc.html
Dec 30 '06 #5

P: n/a
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 ?

Dec 30 '06 #6

P: n/a
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

Dec 30 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.