必须有一个标准函数可以做到这一点......但与此同时:
#include <stdint.h> // uint32_t
#include <limits.h> // INT_MAX
#include <assert.h> // assert
static inline int sub_tcp_sn(uint32_t a, uint32_t b)
{
uint32_t delta = a - b;
return delta <= INT_MAX ? delta : -(int)~delta - 1;
}
请注意,在结果不可表示的情况下是UB,但问题说可以。
如果系统是64位的long long
输入,然后也可以轻松定制和检查范围:
typedef long long sint64_t;
static inline sint64_t sub_tcp_sn_custom_range(uint32_t a, uint32_t b,
sint64_t out_min, sint64_t out_max)
{
assert(sizeof(sint64_t) == 8);
uint32_t delta = a - b;
sint64_t result = delta <= out_max ? delta : -(sint64_t)-delta;
assert(result >= out_min && result <= out_max);
return result;
}
例如,sub_tcp_sn_custom_range(0x10000000, 0, -0xf0000000LL, 0x0fffffffLL) == -0xf00000000
.
通过范围定制,该解决方案可以最大限度地减少所有情况下的范围损失,假设时间戳呈线性行为(例如,环绕 0 没有特殊含义)并且有可用的 64 位类型。