Я думаю, вы говорите о правильной обработке переноса числа. Это довольно просто, на самом деле.
Это не совсем то, что вы сказали (не уверен, почему у вас такой интервал "исключения"), но:
typedef unsigned short uint16_t;
typedef signed short int16_t;
// abstract out 16-bit types in case "short" doesn't correspond to 16bits
bool isEarlier(uint16_t a, uint16_t b)
{
int16_t diff = a-b;
return diff < 0;
}
bool isLater(uint16_t a, uint16_t b)
{
int16_t diff = a-b;
return diff > 0;
}
edit : это имеет "точку ветвления" в diff = -32768, так что если a = 5 и b = 32772, diff = -32767, что меньше 0 и, следовательно, 5 "раньше" «чем 32772. Если a = 5 и b = 32774, diff = -32769 = 32767, что больше 0 и, следовательно, 5« позже », чем 32774. Это определяет« раньше »и« позже »в смысле (а) простейшая математика, и (b), поскольку счетчики циклического переноса могут интерпретироваться как имеющие несколько решений mod 65536, он выбирает решения a и b, которые являются «наиболее близкими» друг к другу относительно круга чисел.
Если a и b отличаются на 32768, то они одинаково далеки друг от друга, и простая математика используется для выбора наиболее простого ... это "нарушает" антисимметричное свойство "ранее" и "позже" в том смысле, что isLater (5 , 32773) верно и isLater (32773,5) также верно. Но как вы узнаете, представляет ли «5» счет 5 или «5» 65541? (так же, как abs (-32768) == -32768 дает странный бессмысленный ответ) Если вы хотите сохранить антисимметрию, например isLater (b, a) == isEarlier (a, b), тогда вы всегда можете сделать это:
bool isLater(uint16_t a, uint16_t b)
{
int16_t diff = b-a;
return diff < 0;
}
Если вы хотите сместить точку ветвления в одном направлении, чтобы это произошло при -32768 + K, используйте вместо этого:
bool isEarlier(uint16_t a, uint16_t b)
{
int16_t diff = a-b-K;
return diff < -K;
}
bool isLater(uint16_t a, uint16_t b)
{
int16_t diff = b-a-K;
return diff < -K;
}
Это больше не использует ближайший; если, например, K = 12768 и a = 5, то для b = 6,7,8,9, ... 20005, isEarlier (a, b) и isLater (b, a) будут истинными, а для b = 20006, 20007, ... 65534, 65535, 0, 1, 2, 3, 4, 5 isEarlier (a, b) и isLater (b, a) будут ложными.
У вас есть определенный выбор интервалов, который отличается от обоснования, которое я использую с числами с циклом. Определенные здесь функции не будут соответствовать вашим потребностям, как указано, но я считаю, что выбор интервала немного необычен. Возможно, вы могли бы объяснить, как вы их определили?