In article <11**********************@f14g2000cwb.googlegroups .com>,

alice <al***********@yahoo.com> wrote:

Please look at the following program:
int main(void)

{

char c;

c = -16;

In C, it is up to the compiler writers to decide whether a plain

"char" variable is "signed" or "unsigned".

If, on your implementation, "char" is signed, then then assignment will

store the -numeric- value you are expecting... but not necessarily the

bit pattern you are expecting.

If, on your implementation, "char" is unsigned, then you would

have an implicit signed-to-unsigned conversion going on. The value

stored would be UCHAR_MAX + 1 - 16; i.e., 240 for the common case

of UCHAR_MAX being 255.

if(c & (0x1<<7) !=0)

printf("TRUE\n");

else

printf("FALSE\n");

return 0;

}
The above program should print TRUE ( as -128 is not equal to 0) but

the above program is printing FALSE. Can anybody please tell why it is

so?

You are counting on a particular bit representation for a negative

value, but C allows implementations to choose from three different

bit representation for negative values. The most common representation

is "twos complement" (-x is 1 plus the bitwise complement of x,

+0 and -0 are the same), but C also allows "ones complement"

(-x is the bitwise complement of x, +0 is "all bits clear", -0 is

"all bits set"), and "signed magnitude" (there is a bit which

does nothing other than hold the sign of the value, and -x has

the same value bits as x but with the sign bit changed.)

Notice that in "signed magnitude" representation in which

a total of 8 bits are stored per character, 1<<7 is outside

the representable positive range (which only uses 7 bits for value)

and so would overflow with undefined results

(most likely that 1<<7 would be 0.)

Notice that in 2s complement signed character representation in which 8

bits are stored per character, 1<<7 would try to represent +128 but

that +127 is the largest possible positive number in that

situation, so the behaviour would be undefined.

I notice that you have used 0x1<<7 instead of 1<<7 . That

suggest to me that you might be thinking that somehow using

the 0x notation indicates an unsigned value. That is not the

case, though: 0x notation merely indicates hexidecimal representation.

If you want to work at the bit level, you should not

*assume* that you are on a 2s complement machine (but it

might be fair to -test- to see if you are, and to abort

the program if you are not.)

You should never assume that char is signed or unsigned.

If you want signed or unsigned char, then code

"signed char" or "unsigned char" explicitly.

When you are working at the bit level, working with signed

values can lead to unexpected results unless you know exactly

what the rules are. If you want to work at the bit level, you

should probably only work with unsigned quantities.

Also, you should not assume that manipulation of literal constants

(such as 1<<7) is working with unsigned values. You should instead

take the care to use the appropriate suffix to indicate that you

want the unsigned version of the constant. For example, 1U << 7

--

All is vanity. -- Ecclesiastes