3

受信したメッセージ番号が特定の範囲内にあるかどうかを確認しようとしています。メッセージ番号がインクリメントされるたびに、番号 10 を期待している場合、番号 10 + 5 のメッセージを受け入れます。したがって、シーケンス番号 10 から 15 です。unsigned int を使用しています。したがって、予想される数が 65532 の場合、65532 + 10 (最小 = 65532 および最大 = 5) を受け入れることができます。受信した番号がこの範囲内にあるかどうかを確認するにはどうすればよいですか?

4

3 に答える 3

6

単純に引き算

unsigned message_number, expected_number;
unsigned range = 5;  // or 10,  OP’s post varies as to the desired range.
if ((message_number - expected_number) <= range) {
  ;  // accept;
}

符号なし算術演算のラップアラウンドは明確に定義されています。

[編集]

message_number上記のソリューションは、 が と同じ場所でラップする場合にうまく機能しunsignedます。次の解決策では、その仮定を行っていませんunsigned short

unsigned maxsequenceplus1_number = 65536LU;
if (((message_number - expected_number)%maxsequenceplus1_number) <= range) {
  ;  // accept;
}

const unsigned maxsequence_number = 65535U; // some power of 2 minus 1
if (((message_number - expected_number)&maxsequence_number) <= range) {
  ;  // accept;
}
于 2013-07-11T04:35:37.763 に答える
1

使用unsignedすると、ある値 k に対して GF(2 k ) 算術演算が得られます [編集: 加算と減算、完全な有限体を実行するのは、はるかに多くの作業です。多分私はいくつかの他の略語を採用する必要がありますか?]. 通常、unsigned shortk は16、32、64unsigned intですunsigned long longが、いずれにせよ少なくとも 16 です (UINT_MAX少なくとも 65535 であるため)。

この種の有限体演算では、単純に 2 つの数値を減算し、結果を制限と比較できます。つまり、「許容値」の範囲が x から x+5 で、実際に受け取った値が y の場合:

unsigned int x, y, diff;
...
diff = y - x;
if (diff <= 5) {
    the value is in range
} else {
    the value is out of range
}

これは、「範囲内」ウィンドウが 2 k-1を超えない限り正常に機能し、 k >= 16 であるため、ウィンドウ スペースが少なくとも 32767 であることを意味します。

unsigned shortC の 1 つのしわを使用する場合は、通常の場合の代わりにunsigned short(signed, plain)に展開されます。したがって、減算を行うにはにキャストする必要があります。intunsigned intINT_MAX >= USHRT_MAXunsigned int

unsigned short x, y, diff;
....
diff = (unsigned int)y - (unsigned int)x;

コードの残りの部分は変更されていません (値 mod 2 kを減らすため、unsigned intへの代入は明確に定義されていることに注意してください)。unsigned short

于 2013-07-11T04:40:49.503 に答える