unsigned char

F

FlyingBird

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
 
C

Clark S. Cox III

FlyingBird said:
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).
 
B

Bill Medland

FlyingBird said:
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.
 
C

cassius

FlyingBird said:
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.
 
E

Eric Sosman

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.
 
B

Bill Medland

Eric said:
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.
 
F

Frederick Gotham

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
 
E

Eric Sosman

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).
 
C

Clark S. Cox III

Bill said:
FlyingBird said:
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).
 
J

Jack Klein

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.
 
C

CBFalconer

Jack said:
FlyingBird said:
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.
 
G

Guest

CBFalconer said:
Jack said:
FlyingBird said:
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.
 
P

Peter Nilsson

Clark said:
FlyingBird said:
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.
Yes, the signed char was promoted in exactly the same way.


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>.]
 
C

CBFalconer

Peter said:
.... 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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top