Interface Design - Random Number Library

Objectives

Interface는 다음 사항들을 고려하여 설계한다.



Random number generator

            int rand(void);  // stdlib.h에 prototype이 정의되어 있음.


#define  RAND_MAX  32767
또는
#define  RAND_MAX  2147483647


많은 응용 분야에서 특정 범위의 random number를 필요로 한다

  • ANSI C rand function을 이용하여 위 경우 모두를 처리할 수 있는 random number generation package를 설계할 수 있다.


    동전 던지기의 경우

    rand() <= RAND_MAX / 2 이면 head  // rand() % 2 == 0 을 조건식으로 사용할 경우는?
    else  tail
    
    #define  HEAD  0
    #define  TAIL  1
    
    int TossCoin(void)
    {
       if (rand() <= RAND_MAX / 2)
          return  HEAD;
       else
          return  TAIL;
    }
    
    
    

    주사위 던지기의 경우

    잘못된 예 1)

    int RollDie(void)
    {
       if (rand() < RAND_MAX / 6) return 1;
       else if (rand() >= RAND_MAX / 6 && rand() < RAND_MAX * 2 / 6) return 2;
       else if (rand() >= RAND_MAX * 2 / 6 && rand() < RAND_MAX * 3 / 6) return 3;
       else if (rand() >= RAND_MAX * 3 / 6 && rand() < RAND_MAX * 4 / 6) return 4;
       else if (rand() >= RAND_MAX * 4 / 6 && rand() < RAND_MAX * 5 / 6) return 5;
       else if (rand() >= RAND_MAX * 5 / 6 && rand() <= RAND_MAX) return 6;
    }
    
    
    

    잘못된 예 2)

    int RollDie(void)
    {
       if (rand() < RAND_MAX / 6) return 1;
       else if (rand() < RAND_MAX * 2 / 6) return 2;
       else if (rand() < RAND_MAX * 3 / 6) return 3;
       else if (rand() < RAND_MAX * 4 / 6) return 4;
       else if (rand() < RAND_MAX * 5 / 6) return 5;
       else return 6;
    }
    
    
    

    잘못된 예 3)

    int RollDie(void)
    {
       int r;
    
       r = rand();
       if (r < RAND_MAX / 6) return 1;
       else if (r < RAND_MAX * 2 / 6) return 2;
       else if (r < RAND_MAX * 3 / 6) return 3;
       else if (r < RAND_MAX * 4 / 6) return 4;
       else if (r < RAND_MAX * 5 / 6) return 5;
       else return 6;
    }
    
    
    

    예 4)

    int RollDie(void)
    {
       int r;
    
       r = rand();
       if (r < RAND_MAX / 6) return 1;
       else if (r < RAND_MAX / 6 * 2) return 2;
       else if (r < RAND_MAX / 6 * 3) return 3;
       else if (r < RAND_MAX / 6 * 4) return 4;
       else if (r < RAND_MAX / 6 * 5) return 5;
       else return 6;
    }
    
    
    

    Generalized random number package design

  • 임의의 두 정수 low와 high 사이의 random number generator

    int RandomInteger(int low, int high);

    알고리즘)

    1. rand function 결과 값을 0 보다 같거나 크고 1 보다 작은 실수 d로 변환 (normalization)
    2. d가 해당 범위의 수를 모두 포함할 수 있도록 확대 (scale)
    3. 소숫점 이하 자리를 떨어버림으로써 d를 정수화. [d는 0에서 (high - low + 1) 사이의 수]
    4. d를 해당 범위로 옮김 (translate; 이동)

  • 위 알고리즘을 구현한 random number package source code (random.c) 와 interface (random.h) 정의

    Interface는

    들을 포함하여야 한다.



    Constant definitions는 보통 #define 문을 사용한다.


    C의 preprocessor 명령

    #include                // compile 시 지정된 file 포함
    #define         // 하나의 symbol로 긴 문자열 대치
    
    
    

    예)

    #include "filename"
    #include <filename>
    
    #define  symbol  replacement text
    
    
    

  • 대치 문자열이 여러 줄에 걸쳐 있을 경우 마지막 행을 제외한 각 행 끝을 '\'로 끝냄.

    예)

    #define  MAX (A, B)  ((A) > (B) ? (A) : (B))
    x = MAX(p+q, r+s); ==> x = ((p+q) > (r+s) ? (p+q) : (r+s)); 로 대치
    
    
    

    잘못 사용 예)

    MAX(i++, j++)
    #define  square(x)  x * x
    
    
    

    #undef 에 의해 정의가 취소될 수 있다.



    조건부 포함 (Conditional inclusion)

    #ifndef  SYMBOL          ==> #if  !define(SYMBOL)
    # define  SYMBOL
    ...
    ...
    #endif
    
    
    #if  SYSTEM==SYSV
    ...
    #elif  SYSTEM== BSD
    ...
    #elif  SYSTEM==WINDOWS
    ...
    #else
    ...
    #endif
    
    
    
    

  • 위에서 작성된 random number package를 사용하기 위해서는 client program은 random.h file을 include하고 random.c의 object code와 link 시켜야 한다. (dicetest.c)

  • 위 random number generator는 똑같은 초기값(seed)에 대해 같은 random number sequence를 return 한다. 그러므로 seed value를 알면 발생되는 수들을 예측할 수 있다.

  • 임의의 seed 값을 사용하여 randomize할 수 있다. (이 경우 time function을 많이 사용)
    void Randomize(void)
    {
       srand((int) time(NULL));       // time.h를 include하여야 함.
    }
    
    
    

    위의 random number interface design에 대한 다음 사항들을 고려해 볼 것.