我怎样才能轻松地检查a <= b <= a+c
模数是否为 256(我们取的值a
和a+c
最接近的值b
)?
基本上我的情况类似于 TCP 中的情况。TCP 期望接收的序列号 ( b
) 不小于它上次接收到的 ( a
),但不大于它上次接收到的 + 偏移量 ( c
)。问题是所有这些都发生在模数上(在 TCP 的情况下,它是 mod 32535,而在我的情况下,是 mod 256)。
抱歉,如果不清楚,请随时询问详细信息,我会更新问题。
一个简单的 C 函数可以做到这一点:
int is_valid (int old_val, int new_val, int offset, int width)
{
if (new_val <= old_val)
/* The only way this can happen is if there was wrap-around.
OR if the `new_val' is invalid. If it is invalid, the next `if'
will catch it. */
new_val += width;
if (new_val > (old_val + offset))
return 0;
return 1;
}
这很容易理解,我认为这才是真正重要的。
在你的情况下:offset = 10
和width = 256
。
注意事项:
new_val + width
并且old_val + offset
适合int
.old_val
和new_val
相同,则认为输入无效。如果这不是您想要的,请更改<=
为<
.old_val
并且new_val
已经是模宽度,即模256。它没有验证这一点。当我使用以下输入运行它时:
int main (void)
{
printf ("%d\n", is_valid (255, 9, 10, 256)); /* Pass. */
printf ("%d\n", is_valid (255, 10, 10, 256)); /* Fail. */
printf ("%d\n", is_valid (0, 10, 10, 256)); /* Pass. */
printf ("%d\n", is_valid (0, 11, 10, 256)); /* Fail. */
printf ("%d\n", is_valid (100, 109, 10, 256)); /* Pass. */
printf ("%d\n", is_valid (100, 110, 10, 256)); /* Pass. */
printf ("%d\n", is_valid (100, 111, 10, 256)); /* Fail. */
return 0;
}
它提供以下输出:
1
0
1
0
1
1
0
template <int N> bool moduloLess (int a, int b)
{
// this is a group, even after modulo!
int d=(b+N-a)%N;
// use the representative in [-N/2-1, N/2] and check whether its greater
// negative means that b was "smaller"
// since we got the representative in [0, N-1], check whether we are greater than N/2
return d*2 <= N;
}
This should do it, if I got your question right...
For your updated question: it should work if you just use moduloLess<256>(b-a, c)
, at least if c is smaller than 128.
对于带有翻转的单调计数器或计时器,要确定是否a
大于b
256 模,您只需检查 if a - b < 128 (mod 256)
。
a > b 的示例:
256 - 206 = 50 (mod 256)
0 - 206 = 50 (mod 256)
20 - 226 = 50 (mod 256)
a < b 的示例:
206 - 256 = 206 (mod 256)
206 - 0 = 206 (mod 256)
226 - 20 = 206 (mod 256)
唯一的技巧是%
C 中的运算符可以给出否定的结果。更好的方法是转换为 1 字节类型(unsigned char
或者uint8_t
,也许)。
因此,对于您的情况,测试将是:
if ((unsigned char)(b - a) < 128 && (unsigned char)(a + c - b) < 128)
定义一个宏,如:
#define COMPARE_MODULUS (a,b,c) ((a)%256) <= ((b) % 256)? ((b) <= ((a)+(c))?true:false):false