这是lwIP源代码中的一个宏:
#define TCP_SEQ_LT(a,b) ((int32_t)((uint32_t)(a) - (uint32_t)(b)) < 0)
Run Code Online (Sandbox Code Playgroud)
用于检查TCP序列号是否小于另一个序列号,考虑序列号何时环绕.它利用了算术包装的事实,但我无法理解这在特定情况下是如何工作的.
任何人都可以解释发生了什么,为什么上述工作?
举一个简单的 4 位整数示例,其中 a = 5 且 b = 6。每个的二进制表示为
a = 0101
b = 0110
Run Code Online (Sandbox Code Playgroud)
现在,当我们减去这些(或取 b 的补码,与 a 相加,然后加 1)时,我们得到以下结果
0101
1001
+ 1
-----
1111
Run Code Online (Sandbox Code Playgroud)
1111 等于 15(无符号)或 -1(有符号,再次使用二进制补码转换)。通过将两个数字转换为无符号数,我们确保如果 b > a,则两者之间的差将是一个大的无符号数,并且设置了它的最高位。当将这个大的无符号数转换为其有符号数时,由于设置的 MSB,我们总是会得到一个负数。
正如 nos 指出的那样,当序列号从最大无符号值回绕到最小值时,宏还将使用上述算术返回最大值 < min,因此它很有用。