需要:Wrappable计数器在哪里 < 并>做"正确的事"
题
我需要一个国允许的溢出和在哪里 < >继续告诉前值中从后面值,对于某些限定的时间间隔。
为了澄清,一个可能的执行将是:
考虑两个这样的柜台 cur
和 dut
(测设备),考虑两个功能:
bool isEarlier(cur, dut) // Is dut earlier than cur?
bool isLater(cur, dut)
cur
和 dut
是16位, cur
只有溢出的,其目前的价值是,让我们说 5
.根据不同的价值的 dut
, ,职能将返回
- 0到16384:isEarlier->
(cur < dut)
,isLater->(cur > dut)
- 16384到32768:isEarlier->假,isLater->真的
- 32768到49152:无效,记录错误
- 49152到65536:isEarlier->真的,isLater->假
我可以写代码我自己,没有问题。我只是懒惰。我知道对于事实,那就是类似的东西在PostgreSQL(事务id包裹),我只是找不到的功能,其实不会。我很确定有类似的东西在Linux内核,可能是一个宏。但neighther谷歌codesearch,也没有查询过/usr/include/linux可以把它了。任何想法,它在哪里?
澄清作用的当前和测设备."无效"是有作为一种保障。作为之间的差异,当前和测设备变得更大,能最终抱怨。
解决方案
我认为你们在谈论处理该环绕的数量圆正确。这是相当容易,实际上。
这不正是你所说的(不知道为什么你有了这些"例外"时间间隔),但:
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;
}
编辑:这有一个"支点"在差异=在-32768,所以,如果a=5和b=32772,diff=-32767这是比0,因此5是"早期"比32772.如果a=5和b=32774,diff=-32769=32767其大于0,因此5是"后"比32774.这个定义了"以前"和"之后"在意义上的(a)简单的数学,以及(b)由于环绕柜台可以被解释为具有多种解决方案,国防部65536,它挑选的解决方案a和b,"最近的"互相对于数量的圈子。
如果a和b相差32768然后他们也同样远和简单的数学是用于挑选容易的...这种"违反"的反对称的财产的"以前"和"之后"在这个意义上,isLater(5,32773)是真正的和isLater(32773,5)也是如此。但是你怎么知道是否"5"代表一个数为5或"5"代表一个数65541?(只是作为abs(在-32768)==在-32768提供了一个奇怪的荒谬解答)如果你想保持反例如isLater(b)==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)将是真实的,并对于b=20006,20007,...65534, 65535, 0, 1, 2, 3, 4, 5 isEarlier(a、b)和isLater(b)将是错误的。
你有一个特定选择的时间间隔是不同的理由我的使用与环绕数字。功能定义这里不会满足你的需要作为说明,但我找到这些选择的时间间隔一点特殊。也许你可以解释你怎么确定他们?
其他提示
第一个计算差值,然后检查进入哪个窗口也下降。
因为它是如此的简单的尺寸过去的/未来/错误windows变化,你必须自己做。
好的,为的记录。这里是我的解决方案,这是什么我的意思是:
#include <stdint.h>
void increase_cyclic_counter (uint16_t *cnt)
{
#ifdef CYCLIC_COUNTER_EXPLICIT_WRAP
if (*cnt < 2^16-1)
*cnt++;
else
*cnt = 0;
#else
*cnt++;
#endif
}
#define SAME 1
#define LATER 0
#define EARLIER 2
#define FORBIDDEN -1
/* dut (device under test) is tested against cur
* returns:
* EARLIER (LATER) if dut happened earlier (later) in the sequence than cur
* SAME if dut == cur
* FORBIDDEN if dut and cur are that far away in the cyclic sequence
* that no unambigious jugement is possible
*
* The basic idea is the same as with two-character year codes, where
* '97' stands for 1997 and '11' stands for 2011. '50' is regarded as
* too ambigous and therefore rejected.
*
* The implementation splits the short integer range 0-65535 into 4 parts:
* 0-16383, 16384-32767, 32768-49151, 49152-65536
* With cur and dut in the same range, normal arithmetics apply, else the
* ranges are compared to each other.
*/
int test_cyclic_counter (uint16_t cur, uint16_t dut)
{
switch (((int)(cur>>14)) - ((int)(dut>>14)))
{
case 0: // same range
if (dut < cur)
return EARLIER;
else if (dut == cur)
return SAME;
else
return LATER;
case 1:
case -3:
return EARLIER;
case 3:
case -1:
return LATER;
default:
return FORBIDDEN;
}
}
在我看来你只写了:).为什么不把你邮到C码?
记住,你不能得到">"和"<"做你想要什么。它们适用于数字,并没有操作超载。同样的道理也适用于你的异常;C没有例外。
你可以写一些访问的功能,将把未签署的整体类型的方式,那不会很难。(C溢出是不确定的用于签署了整体的种类,虽然在最现代化的系统环绕.) 它不会是困难的。