Different Data Types - Signed and Unsigned

358 views Asked by At

I just executed the following code

main()
{
   char a = 0xfb;
   unsigned char b = 0xfb;
   printf("a=%c,b=%c",a,b);
   if(a==b) {
     printf("\nSame");
   }
   else {
     printf("\nNot Same");
   }
}

For this code I got the answer as

a=? b=?

Different

Why don't I get Same, and what is the value for a and b?

4

There are 4 answers

1
chqrlie On BEST ANSWER

There are 2 cases to consider:

  • if the char type is unsigned by default, both a and b are assigned the value 251 and the program will print Same.
  • if the char type is signed by default, which is alas the most common case, the definition char a = 0xfb; has implementation defined behavior as 0xfb (251 in decimal) is probably out of range for the char type (typically -128 to 127). Most likely the value -5 will be stored into a and a == b evaluates to 0 as both arguments are promoted to int before the comparison, hence -5 == 251 will be false.

The behavior of printf("a=%c,b=%c", a, b); is also system dependent as the non ASCII characters -5 and 251 may print in unexpected ways if at all. Note however that both will print the same as the %c format specifies that the argument is converted to unsigned char before printing. It would be safer and more explicit to try printf("a=%d, b=%d\n", a, b);

With gcc or clang, you can try recompiling your program with -funsigned-char to see how the behavior will differ.

4
Lee Daniel Crocker On

The line if (a == b)... promotes the characters to integers before comparison, so the signedness of the character affects how that happens. The unsigned character 0xFB becomes the integer 251; the signed character 0xFB becomes the integer -5. Thus, they are unequal.

0
krpra On

char stores from -128 to 127 and unsigned char stores from 0 to 255. and 0xfb represents 251 in decimal which is beyond the limit of char a.

1
Vlad from Moscow On

According to the C Standard (6.5.9 Equality operators)

4 If both of the operands have arithmetic type, the usual arithmetic conversions are performed....

The usual arithmetic conversions include the integer promotions.

From the C Standard (6.3.1.1 Boolean, characters, and integers)

2 The following may be used in an expression wherever an int or unsigned int may be used: ...

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions.

So in this equality expression

a == b

the both operands are converted to the type int. The signed operand ( provided that the type char behaves as the type signed char) is converted to the type int by means of propagating the sign bit.

As result the operands have different values due to the difference in the binary representation.

If the type char behaves as the type unsigned char (for example by setting a corresponding option of the compiler) then evidently the operands will be equal.