受信したメッセージ番号が特定の範囲内にあるかどうかを確認しようとしています。メッセージ番号がインクリメントされるたびに、番号 10 を期待している場合、番号 10 + 5 のメッセージを受け入れます。したがって、シーケンス番号 10 から 15 です。unsigned int を使用しています。したがって、予想される数が 65532 の場合、65532 + 10 (最小 = 65532 および最大 = 5) を受け入れることができます。受信した番号がこの範囲内にあるかどうかを確認するにはどうすればよいですか?
3 に答える
単純に引き算
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;
}
使用unsigned
すると、ある値 k に対して GF(2 k ) 算術演算が得られます [編集: 加算と減算、完全な有限体を実行するのは、はるかに多くの作業です。多分私はいくつかの他の略語を採用する必要がありますか?]. 通常、unsigned short
k は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 short
C の 1 つのしわを使用する場合は、通常の場合の代わりにunsigned short
(signed, plain)に展開されます。したがって、減算を行うにはにキャストする必要があります。int
unsigned int
INT_MAX >= USHRT_MAX
unsigned int
unsigned short x, y, diff;
....
diff = (unsigned int)y - (unsigned int)x;
コードの残りの部分は変更されていません (値 mod 2 kを減らすため、unsigned int
への代入は明確に定義されていることに注意してください)。unsigned short