更新时间:2023-11-24 19:50:52
必须有一个标准函数可以执行此操作……但与此同时:
There must be a standard function that does this... but in the meantime:
#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,但问题是确定的.
Note that it is UB in the case that the result is not representable, but the question said that was OK.
如果系统具有64位long long
类型,则可以轻松地自定义和检查范围:
If the system has a 64-bit long long
type, then the range can easily be customized and checked as well:
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位类型.
With the range customization, this solution minimizes range loss in all situations, assuming timestamps behave linearly (for example, no special meaning to wrapping around 0) and a singed 64-bit type is available.