4

オーバーフローが許可され、定義された間隔で < > が後の値から以前の値を伝え続けるクーターへのコードが必要です。

明確にするために、1つの可能な実装は次のとおりです。

そのような 2 つのカウンターcurdut(テスト対象のデバイス) を考え、2 つの機能を考えます。

bool isEarlier(cur, dut)    // Is dut earlier than cur?
bool isLater(cur, dut)

curdutは 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カーネルにそのようなもの、おそらくマクロがあると確信しています。しかし、Google のコード検索でも、/usr/include/linux に対する grep でも、それを有効にすることはできませんでした。それがどこにあるのでしょうか?

cur と dut の役割を明確にしました。「無効」は保護手段としてあります。cur と dut の差が大きくなると、関数は最終的に不平を言います。

4

5 に答える 5

3

数字の円の回り込みを正しく処理することについて話していると思います。実際、それは非常に簡単です。

これはあなたが言ったことを正確には行いません(なぜあなたがその「例外」間隔を持っているのかわかりません)が、:

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;
}

編集:これはdiff = -32768に「分岐点」があるため、a=5およびb=32772の場合、diff = -32767は0未満であり、したがって5は32772より「早い」です。a=5およびb = 32774、diff = -32769 = 32767これは0より大きいため、5は32774より「遅い」です。これは、(a)最も単純な計算、および(b)の意味で、「早い」と「遅い」を定義します。ラップアラウンドカウンターは、複数のソリューションmod 65536を持っていると解釈でき、数字の円に関して互いに「最も近い」aとbのソリューションを選択します。

aとbが32768異なる場合、それらは等しく離れており、簡単な計算を使用して最も簡単に選択できます...これは、isLater(5,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(a、b)とisLater(b、a)はtrueになり、 b = 20006、20007、... 65534、65535、0、1、2、3、4、5 isEarlier(a、b)およびisLater(b、a)はfalseになります。

ラップアラウンド数で使用する理論的根拠とは異なる、特定の間隔の選択があります。ここで定義されている関数は、述べられているようにあなたのニーズを満たしませんが、間隔のそれらの選択は少し独特だと思います。おそらく、あなたはそれらをどのように決定したかを説明できますか?

于 2009-01-19T17:41:06.437 に答える
1

最初に差を計算し、次にそれがどのウィンドウに該当するかを確認します。

とてもシンプルで、過去/未来/エラーウィンドウのサイズが異なるため、自分で行う必要があります。

于 2009-01-19T16:14:55.487 に答える
1

わかりました、記録のために。これが私の解決策です。これが私が意味したことです:

#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;
    }
}
于 2009-01-20T00:46:28.370 に答える
0

">"と"<"をCでやりたいことを実行することはできないことに注意してください。これらは数値にのみ適用され、演算子のオーバーロードはありません。同じことがあなたの例外にも当てはまります。Cには例外はありません。

符号なし整数型をそのように扱ういくつかのアクセス関数を書くことができ、それは難しくありません。(Cでは、オーバーフローは符号付き整数型では定義されていませんが、最近のほとんどのシステムではラップアラウンドします。)それほど難しくはありません。

于 2009-01-19T16:04:23.243 に答える
0

あなたがちょうどそれを書いたように私には思えます:)。投稿をCコードに翻訳してみませんか?

于 2009-01-19T15:56:28.970 に答える