-3

我怎样才能轻松地检查a <= b <= a+c模数是否为 256(我们取的值aa+c最接近的值b)?

基本上我的情况类似于 TCP 中的情况。TCP 期望接收的序列号 ( b) 不小于它上次接收到的 ( a),但不大于它上次接收到的 + 偏移量 ( c)。问题是所有这些都发生在模数上(在 TCP 的情况下,它是 mod 32535,而在我的情况下,是 mod 256)。

抱歉,如果不清楚,请随时询问详细信息,我会更新问题。

4

4 回答 4

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 = 10width = 256

注意事项:

  1. 输入应该足够小new_val + width并且old_val + offset适合int.
  2. 如果old_valnew_val相同,则认为输入无效。如果这不是您想要的,请更改<=<.
  3. 该函数假定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
于 2012-07-16T12:23:03.487 回答
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.

于 2012-07-16T12:06:59.197 回答
0

对于带有翻转的单调计数器或计时器,要确定是否a大于b256 模,您只需检查 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)
于 2012-07-16T12:12:36.633 回答
0

定义一个宏,如:

#define COMPARE_MODULUS (a,b,c)  ((a)%256) <= ((b) % 256)? ((b) <= ((a)+(c))?true:false):false
于 2012-07-16T12:27:50.330 回答