:Wrappableカウンター < >のいるところが大きいと"
質問
さんありがとうございます。ドをcouterさせてもらっているのであって、オーバーフローが < >続きを教えて以前の値から後の値は、一定間隔で出ています。
を明らかにすることを可能とし実施することはできない。
と考えらどのようなカウンター cur
や dut
(試験デバイス、二つの機能
bool isEarlier(cur, dut) // Is dut earlier than cur?
bool isLater(cur, dut)
cur
や dut
16ビット cur
だが溢れ、その現在の値がしましょう 5
.の値によって dut
, の機能を返します
- 0 16384:isEarlier->
(cur < dut)
,isLater->(cur > dut)
- 16384への32768:isEarlier->falseの場合、isLater->true
- 32768にしてください49152:無効なログインエラー
- してください49152に65536:isEarlier->true、isLater->false
うに記述することができるコードも問題ありません。私は怠け者.知っていたこのようなものがありまPostgreSQL(取引idを包む)だけでな検索機能が実際にいます。っていくようなものがありまをLinuxカーネルのうのをクリックします。がneighther Google codesearchもgrep over/usr/include/linuxがあります。そのアイデアです。
明らかに役cur、まずdutにを"無効"であるとして保護.としての違いをcur、dutになりが大きくなり、機能が不.
解決
私はあなたが正しく数円の回り込みを扱う話をしていると思います。それは実際には、非常に簡単です。
これは(あなたがその「例外」の間隔を持っている理由ではないことを確認)あなたが言ったことを正確に行うのではなく、ます:
typedef unsigned short uint16_t;
typedef signed short int16_t;
// abstract out 16-bit types in case "short" doesn't correspond to 16bits
bool isEarlier(uint16_t a, uint16_t b)
{
int16_t diff = a-b;
return diff < 0;
}
bool isLater(uint16_t a, uint16_t b)
{
int16_t diff = a-b;
return diff > 0;
}
編集:これは、差分= -32768の "分岐点" を有するようになる= 5、B = 32772、差分= -32767が0未満ひいては5された場合に "以前の」より32772.もし0より大きく、従って、5である= 5、B = 32774、差分= -32769 = 32767 『以前『と 『後』の意味で』これは定義32774.より』後(A )最も単純な数学、および(b)はラップアラウンドカウンターは複数のソリューションをMOD 65536を有すると解釈することができるので、それは数字の円に対して互いに「最も近い」であり、Bの溶液を選びます。
とbが、これはisLater(5その「以前」と「後に」の意味での反対称プロパティを「違反」...そして、彼らは同じように遠く離れていると、単純な数学が最も簡単なを選択するために使用される32768によって異なる場合、32773)が真であるとisLater(32773,5)も真です。しかし、どのように「5」は5の数を表し、または「5」65541の数を表しているかどうかを知っていますか?あなたは、例えば反対称性を維持したい場合は(単にABSなど(-32768)== -32768奇数無意味な答えを与えます) isLater(B、A)== isEarlier(a、b)は、その後、あなたは常にこの操作を行うことができます:
bool isLater(uint16_t a, uint16_t b)
{
int16_t diff = b-a;
return diff < 0;
}
あなたの代わりにこれを使用し、その後、-32768 + Kで発生するバイアスに一方向の分岐点をご希望の場合:
bool isEarlier(uint16_t a, uint16_t b)
{
int16_t diff = a-b-K;
return diff < -K;
}
bool isLater(uint16_t a, uint16_t b)
{
int16_t diff = b-a-K;
return diff < -K;
}
これはもはや最も近い使用しません。もし、例えば、K = 12768であり、a = 5、その後、B = 6,7,8,9のため、... 20005、isEarlier(b)およびisLater(B、A)が真である、とのためであろうB = 20006、20007、... 65534、65535、0、1、2、3、4、5 isEarlier(b)およびisLater(B、A)偽になります。
私はラップアラウンド番号を使う根拠と異なる間隔の特定の選択肢を持っています。述べたように、ここで定義された関数は、あなたのニーズを満たしていないだろうが、私は間隔少し独特のこれらの選択を見つけます。おそらくあなたは、あなたがそれらをどのように決定したか説明できる?
他のヒント
まず、それが属するウィンドウの中にチェックし、差異を計算します。
は、それはとても簡単ですので、過去/未来/エラー・ウィンドウの大きさは、あなたがそれを自分で行う必要があり、変わります。
[OK]を、レコードの。ここに私の解決策がある、これは私が何を意味するのかである。
#include <stdint.h>
void increase_cyclic_counter (uint16_t *cnt)
{
#ifdef CYCLIC_COUNTER_EXPLICIT_WRAP
if (*cnt < 2^16-1)
*cnt++;
else
*cnt = 0;
#else
*cnt++;
#endif
}
#define SAME 1
#define LATER 0
#define EARLIER 2
#define FORBIDDEN -1
/* dut (device under test) is tested against cur
* returns:
* EARLIER (LATER) if dut happened earlier (later) in the sequence than cur
* SAME if dut == cur
* FORBIDDEN if dut and cur are that far away in the cyclic sequence
* that no unambigious jugement is possible
*
* The basic idea is the same as with two-character year codes, where
* '97' stands for 1997 and '11' stands for 2011. '50' is regarded as
* too ambigous and therefore rejected.
*
* The implementation splits the short integer range 0-65535 into 4 parts:
* 0-16383, 16384-32767, 32768-49151, 49152-65536
* With cur and dut in the same range, normal arithmetics apply, else the
* ranges are compared to each other.
*/
int test_cyclic_counter (uint16_t cur, uint16_t dut)
{
switch (((int)(cur>>14)) - ((int)(dut>>14)))
{
case 0: // same range
if (dut < cur)
return EARLIER;
else if (dut == cur)
return SAME;
else
return LATER;
case 1:
case -3:
return EARLIER;
case 3:
case -1:
return LATER;
default:
return FORBIDDEN;
}
}
あなたがそれを書いた私には思える:)。 なぜ、あなたの投稿は、いくつかのCコードに変換していませんか?
ベアは心の中であなたが「>」を取得することができず、その「<」あなたは彼らが数字のみに適用され、そして何演算子のオーバーロードはありませんCでやりたいです。同じことは、あなたの例外に適用されます。 Cは例外を持っていません。
あなたはそのように符号なし整数型を扱っていました、いくつかのアクセス関数を書くことができ、それは難しいことではないでしょう。 (ほとんどの現代のシステムでは、それはラップアラウンドがCにおいて、オーバーフローは、符号付き整数タイプの未定義である。)それは困難ではないであろう。