Я использую uint16_t
как счетчик последовательности в сетевом протоколе. Этот счетчик обычно обертывается, как ожидалось. Когда получатель получает пакет, он проверяет этот счетчик на самый последний полученный, чтобы увидеть, является ли он новым пакетом или пакетом вне очереди.
При сравнении порядковых номеров необходимо учитывать значение обхода. Итак, если, например, последний порядковый номер был 0x4000
, то порядковый номер от 0x4001
до 0xBFFF
является более новым, а порядковый номер от 0xC000
до 0xFFFF
и от 0x0000
до 0x3FFF
равен меньше.
В настоящее время я делаю следующее:
uint16_t last;
uint16_t current;
...
// read in values for last and current
...
if ((int16_t)(current - last) > 0) {
printf("current is newer\n");
} else {
printf("current is older (or same)\n");
}
Вычитая два и обрабатывая результат как a int16_t
, я легко могу видеть, что больше и на сколько. Например, если текущий порядковый номер не менее 5 меньше последнего, то i.e ((int16_t)(current - last) < -5)
, я могу предположить, что это не связано с обычным переупорядочением пакетов и удалением пакета.
Я понимаю, что подписанное wraparound - это undefined, но в этом случае я обрабатываю значение unsigned, подписанное для сравнения. Это вызывает поведение undefined, и если да, то каким будет лучший способ сделать этот тип сравнения?