Я использую 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, и если да, то каким будет лучший способ сделать этот тип сравнения?