我如何轻松检查a <= b <= a+c
,模数256(我们采用最接近a
的{{1}}和a+c
的值)?
基本上我处于类似TCP中发现的情况。 TCP期望接收的序列号(b
)不小于上次接收的序列号(b
),但不大于上次接收的序列号+偏移量a
)。问题是所有这些都发生在模数中(在TCP的情况下,它的mod为32535,在我的情况下,mod 256)。
对不起,如果不清楚,请随时询问详情,我会更新问题。
答案 0 :(得分:1)
执行此操作的简单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
答案 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;
}
如果我的问题正确的话,应该这样做......
对于您的更新问题:如果您只使用moduloLess<256>(b-a, c)
,它应该有效,至少如果c小于128。
答案 2 :(得分:0)
对于具有翻转的单调计数器或计时器,要确定a
是否大于b
,模256,您只需检查是否a - b < 128 (mod 256)
。
&gt;的示例B:
256 - 206 = 50 (mod 256)
0 - 206 = 50 (mod 256)
20 - 226 = 50 (mod 256)
&lt; 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)
答案 3 :(得分:0)
定义一个像:
的宏#define COMPARE_MODULUS (a,b,c) ((a)%256) <= ((b) % 256)? ((b) <= ((a)+(c))?true:false):false