Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does the signedness of an integer really matter?

Tags:

c

signedness

Due to the way conversions and operations are defined in C, it seems to rarely matter whether you use a signed or an unsigned variable:

uint8_t u; int8_t i;

u = -3;    i = -3;
u *= 2;    i *= 2;
u += 15;   i += 15;
u >>= 2;   i >>= 2;

printf("%u",u); // -> 2
printf("%u",i); // -> 2

So, is there a set of rules to tell under which conditions the signedness of a variable really makes a difference?

like image 305
AndreKR Avatar asked Nov 28 '22 07:11

AndreKR


2 Answers

It matters in these contexts:

  • division and modulo: -2/2 = 1, -2u/2 = UINT_MAX/2-1, -3%4 = -3, -3u%4 = 1
  • shifts. For negative signed values, the result of >> and << are implementation defined or undefined, resp. For unsigned values, they are always defined.
  • relationals -2 < 0, -2u > 0
  • overflows. x+1 > x may be assumed by the compiler to be always true iff x has signed type.
like image 199
jpalecek Avatar answered Dec 09 '22 18:12

jpalecek


Yes. Signedness will affect the result of Greater Than and Less Than operators in C. Consider the following code:

unsigned int a = -5;
unsigned int b = 7;

if (a < b)
    printf("Less");
else
    printf("More");

In this example, "More" is incorrectly output, because the -5 is converted to a very high positive number by the compiler.

This will also affect your arithmetic with different sized variables. Again, consider this example:

unsigned char a = -5;
signed short b = 12;

printf("%d", a+b);

The returned result is 263, not the expected 7. This is because -5 is actually treated as 251 by the compiler. Overflow makes your operations work correctly for same-sized variables, but when expanding, the compiler does not expand the sign bit for unsigned variables, so it treats them as their original positive representation in the larger sized space. Study how two's compliment works and you'll see where this result comes from.

like image 20
Nicholas Flynt Avatar answered Dec 09 '22 17:12

Nicholas Flynt