c ++算法模数

时间:2012-07-16 11:39:33

标签: c++ c algorithm

我如何轻松检查a <= b <= a+c,模数256(我们采用最接近a的{​​{1}}和a+c的值)?

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

对不起,如果不清楚,请随时询问详情,我会更新问题。

4 个答案:

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

<强>注意事项:

  1. 输入应足够小,new_val + widthold_val + offset适合int
  2. 如果old_valnew_val相同,则输入视为无效。如果这不是您想要的,请将<=更改为<
  3. 该函数假定old_valnew_val已经是模数宽度,即模256。它没有验证这一点。
  4. 当我使用以下输入运行它时:

    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 charuint8_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