How does unsigned subtraction work when flowing around?

This is the macro in lwIP source code:

#define TCP_SEQ_LT(a,b) ((int32_t)((uint32_t)(a) - (uint32_t)(b)) < 0) 

Used to check if the TCP sequence number is less than the other, taking into account when the sequence numbers are wrapped. It uses the fact that arithmetic is wrapped, but I cannot figure out how this works in this particular case.

Can someone explain what is happening and why it works?

+6
source share
3 answers

Take a simple 4-bit integer example, where a = 5 and b = 6. Each binary representation will be

 a = 0101 b = 0110 

Now, when we subtract them (or take two additions to b, sum with a and add 1), we get the following

 0101 1001 + 1 ----- 1111 

1111 is equal to 15 (unsigned) or -1 (signed, translated again using two additions). By casting two unsigned numbers, we guarantee that if b> a, the difference between them will be a large unsigned number and will have the highest bit. When translating this large unsigned number into its signed counterpart, we will always receive a negative number due to the established MSB.

As nos pointed out, when the sequence number wraps from the maximum unsigned value back to min, the macro also returns that the maximum value is <min using the above arithmetic, hence its usefulness.

+3
source

Because it is first distinguished as a signed integer before its comparison with zero. Remember that the first bit, read from left to right, defines the sign in the quantity signed, but is used to increase the value of unsigned int range with an extra bit.

Example: let's say you have a 4-bit unsigned number. This means that 1001 is 17. But as a signed integer, it will be -1.

Now let's say that we made b0010 - b0100. It ends with b1110. Unsigned is 14, and the signature is -6.

0
source

In a wrapper, a will be much larger than b. If you subtract them, the result will also be very large, i.e. Its high order bit will be set. If you then process the result as a sign value, the big difference will turn into a negative number less than 0.

If you had 2 consecutive 2G numbers, that would not work, but that would not happen.

0
source

Source: https://habr.com/ru/post/943653/


All Articles