我认为你在谈论如何正确处理数字环的循环。实际上,这很容易。
这并没有完全按照你说的做(不确定为什么要有那个“exception”间隔),但是:
typedef unsigned short uint16_t;
typedef signed short int16_t;
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;
}
编辑:这个函数在diff=-32768时有一个“分支点”,所以如果a=5且b=32772,则diff=-32767,小于0,因此5比32772“更早”。如果a=5且b=32774,则diff=-32769=32767,大于0,因此5比32774“更晚”。这定义了“更早”和“更晚”的含义,既是最简单的数学概念,也是因为环形计数器可以被解释为在模65536下具有多个解决方案,它选择了与数字圆相对接近的a和b的解决方案。
如果a和b相差32768,则它们之间的距离相等,使用最简单的数学方法来选择最容易的...这“违反了”“更早”和“更晚”的反对称性,因为isLater(5,32773)为真,而isLater(32773,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;
}
现在不再使用closest函数;例如,当K=12768,a=5时,对于b=6,7,8,9,... 20005,isEarlier(a,b)和isLater(b,a)将为true,并且对于b=20006,20007,... 65534,65535,0,1,2,3,4,5,isEarlier(a,b)和isLater(b,a)将为false。
您有一种特定的间隔选择方式,与我在环绕数字中使用的原理不同。这里定义的函数不能满足您所述的需求,但我认为那些间隔选择有点奇怪。也许您可以解释一下如何确定它们?