Search code examples
calgorithmunsigned-integer

Going below zero in unsigned integer operations


I want to deduce a list of 16-bit unsigned integers from another list of 16-bit unsigned integers.

For example, given the list:

10000, 12349, 32333, 3342

and I know the first integer of the other list is 0, now I want to deduce the rest. The mapping is to subtract 10000 from them, I got

0, 2349, 22333, 58878

where 58878 = (3342-10000+65536) modulo 65536 as the result of a wrapping.

The pseudocode is something like:

 void deduce(u_int16_t list1[100], u_int16_t *list2[100], u_int16_t first)
 {
      int diff = first - list1[0];
      for (i = 0; i < 100; i++)
          (*list2)[i] = (list1[i] + diff + 65536) % 65536;
 }

but we know that there is no minus number in unsigned integers.

so how to do the mapping(or deduction)?

thanks!


Solution

  • unsigned integers variables can be subtracted more than they contain - if I understand correctly the question.

    u_int16_t u = 10;
    u -= 20; // => u = u - 20;
    printf("%x, %u\n", u, u); // => fff6, 65526
    

    The difference is

    • when displayed, u does not show a negative value - ie the MSb (most significant bit, ie bit 15) is interpreted (here) as 215, the next as 214 etc...
    • when extended (eg to 32 bits) the MBb is not propagated from bit 16 to bit 31 (as they would be if signed) - they're 0
    • when right shifted the value MSb is always 0 (would be the same as previous MSb if signed, e.g 1 for a negative value)

    So your mapping will keep working with u_int16_t (and you don't need the % modulo 65536 if you work with that type everywhere since anyway the values are on 16 bits - the modulo is implicit).