문제

오버플로가 허용되는 쿠터에게 코드가 필요하며 여기서 <> 정의 된 간격에 대해 <> 이후 값에서 이전 값을 계속 알려줍니다.

명확히하기 위해 하나의 가능한 구현은 다음과 같습니다.

그러한 카운터를 고려하십시오 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 (Transaction IDS Wrap)에 그런 것이 있다는 것을 알고 있습니다. 실제로 수행하는 기능을 찾을 수 없었습니다. 나는 Linux 커널, 아마도 매크로에 그런 것이 있다고 확신합니다. 그러나 이웃 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;
}

편집하다: 이것은 diff = -32768에 "분기점"이 있으므로 a = 5 및 b = 32772 인 경우 diff = -32767은 0보다 작고 5는 32772보다 "이전"입니다. = 32774, diff = -32769 = 32767은 0보다 크고 5는 32774보다 "나중에" "나중에"(a) 가장 단순한 수학의 의미에서 "이전"및 "나중에"를 정의합니다. 카운터는 다중 솔루션 모드 65536을 갖는 것으로 해석 될 수 있으며, 숫자 원과 관련하여 서로 "가장 가까운"A와 B의 솔루션을 선택합니다.

A와 B가 32768만큼 다르면 동일하게 멀리 떨어져 있고 간단한 수학은 가장 쉬운 선택에 사용됩니다 ... 이것은 "이전"과 "나중에"의 비대칭 속성을 "위반자"(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)가 사실이며 B = 20006, 20007, ... 65534, 65535, 0, 1, 2, 3, 4, 5 Isearlier (A, B) 및 Islater (B, A)는 거짓입니다.

랩 어라운드 번호와 함께 사용하는 이론적 근거와 다른 특정 간격 선택이 있습니다. 여기에 정의 된 기능은 언급 된대로 귀하의 요구를 충족시키지 못하지만 간격의 선택이 약간 독특하다고 생각합니다. 아마도 당신은 당신이 그들을 어떻게 결정했는지 설명 할 수 있습니까?

다른 팁

먼저 차이를 계산 한 다음 어떤 창이 떨어지는 지 확인하십시오.

너무 간단하고 과거/미래/오류의 크기가 다양하기 때문에 직접해야합니다.

좋아, 기록을 위해. 여기 내 해결책이 있습니다. 이것이 제가 의미하는 바입니다.

#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에서는 오버플로가 서명 된 적분 유형에 대해 정의되지 않지만 대부분의 최신 시스템에서는 포장됩니다.) 그렇게 어렵지는 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top