c - 需要 : Wrappable Counter where < and > do "the right thing"

标签 c count overflow

我需要允许溢出的代码,其中 < > 在某个定义的时间间隔内继续区分较早的值和较晚的值。

澄清一下,一种可能的实现方式是:

考虑两个这样的计数器 curdut (被测设备),考虑两个功能:

bool isEarlier(cur, dut)    // Is dut earlier than cur?
bool isLater(cur, dut)

curdut是 16 位,cur刚刚溢出,它的当前值是,比方说5 .取决于 dut 的值, 函数将返回

  • 0 到 16384:isEarlier -> (cur < dut) , isLater -> (cur > dut)
  • 16384 到 32768:isEarlier -> false,isLater -> true
  • 32768 到 49152:无效,日志错误
  • 49152 到 65536:isEarlier -> true,isLater -> false

我可以自己写代码,没问题。我只是懒惰。我确实知道 PostgreSQL 中有类似的东西(事务 ID 换行),我只是找不到实际执行它的函数。我很确定 Linux 内核中有类似的东西,可能是一个宏。但是无论是 Google codesearch 还是 grep over/usr/include/linux 都无法打开它。知道它在哪里吗?

阐明了 cur 和 dut 的作用。 “无效”是一种保障。随着 cur 和 dut 之间的差异越来越大,函数最终会报错。

最佳答案

我认为您是在谈论正确处理数字圈的环绕。实际上,这很容易。

这并没有完全按照你说的去做(不知道为什么你有那个“异常”间隔),但是:

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;
}

编辑:这在 diff=-32768 处有一个“分支点”,因此如果 a=5 和 b=32772,diff=-32767 小于 0,因此 5 是“比 32772 早”。如果 a=5 和 b=32774,则 diff=-32769=32767 大于 0,因此 5 比 32774“晚”。这定义了 (a ) 最简单的数学,和 (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;
}

这里不再使用closest;例如,如果 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) 将为假。

您有一个特定的间隔选择,这与我使用环绕数字的基本原理不同。此处定义的函数不能满足您所述的需求,但我发现这些间隔的选择有点奇怪。或许您可以解释一下您是如何确定它们的?

关于c - 需要 : Wrappable Counter where < and > do "the right thing",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/458060/

相关文章:

结构数组上的冲突类型错误

我们可以更改指针指向的字符串字符吗?

perl - 命令行 "sort | uniq -c | sort -n"的替代方案

overflow - Wumpus游戏的make-city-edges函数导致堆溢出

html - CSS 溢出不遵守填充

c - C代码如何调用汇编代码(例如优化的strlen)?

c - 为什么函数会被跳过而不被读取?

sql-server - SQL 查询返回 24 小时,每小时计数,即使不存在值?

sql - 如何选择两个不同列的计数?

google-chrome - 谷歌浏览器中的溢出问题