[C] 난수 생성

김나정·2024년 5월 23일
0

C

목록 보기
7/8
post-thumbnail

이번 포스트에서는 C언어에서 난수 생성에 대해서 구체적인 내용을 다뤘다.
개념과 용어들이 너무 헷갈려서 용어부터 자세하게 공부해보았다.


용어 정리 : 시드, 시퀀스

📒시드 (Seed)

: 난수 생성기의 초기 값

📒난수 시퀀스 (Sequence)

: 난수 생성기가 시드 값을 기반으로 생성하는 일련의 난수들의 순서

비유 : 시드는 씨앗과 같고 시퀀스는 씨앗에서 자라는 식물의 순서와 같다. 같은 씨앗에서 항상 같은 식물이 자라는 것처럼, 같은 시드 값에서 항상 같은 난수 시퀀스가 생성된다.


📌고정된 시드와 난수 시퀀스

고정된 시드

: srand(1234)와 같이 고정된 시드 값을 사용하면, 난수 생성기는 항상 같은 초기 상태에서 시작한다. 따라서 rand() 함수가 생성하는 난수 시퀀스는 항상 동일하다.

시드를 설정하지 않는 경우

: 대부분의 C 라이브러리 구현에서는 srand()를 호출하지 않으면(=rand()만 사용한 경우), 시드가 기본값(예: 1)으로 설정된다. 이 경우에도 rand() 함수는 항상 동일한 난수 시퀀스를 생성한다.

즉 고정된 시드는 시드를 설정하지 않은 경우와 유사한 결과값을 보여준다.


📌동일한 난수 시퀀스? (예시를 통해 이해)

case1🔍.시드 값을 설정하지 않은 경우, 'rand()'

코드

#include <stdio.h>
#include <stdlib.h>

int main() {
    for (int i = 0; i < 5; i++) {
        int randomNumber = rand(); // 난수 생성
        printf("Random number %d: %d\n", i + 1, randomNumber);
    }
    return 0;
}

실행 결과

Random number 1: 1804289383
Random number 2: 846930886
Random number 3: 1681692777
Random number 4: 1714636915
Random number 5: 1957747793

다시 실행해도

Random number 1: 1804289383
Random number 2: 846930886
Random number 3: 1681692777
Random number 4: 1714636915
Random number 5: 1957747793

여전히 동일한 숫자가 동일한 순서로 출력되는걸 볼 수 있다.
이는 rand()함수가 항상 같은 초기 상태에서 시작하기 때문이다.
따라서, 시드 값을 설정하지 않으면 매번 동일한 난수 시퀀스를 생성하게 된다.

case2🔍. 고정된 시드 값을 설정한 경우, srand(1234)

코드

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(1234); // 시드 값을 설정
    for (int i = 0; i < 5; i++) {
        int randomNumber = rand(); // 난수 생성
        printf("Random number %d: %d\n", i + 1, randomNumber);
    }
    return 0;
}

실행 결과

Random number 1: 207482415
Random number 2: 1790989824
Random number 3: 2035175616
Random number 4: 77048696
Random number 5: 24794531

다시 실행해도

Random number 1: 207482415
Random number 2: 1790989824
Random number 3: 2035175616
Random number 4: 77048696
Random number 5: 24794531

여전히 동일한 숫자가 동일한 순서로 출력되는걸 볼 수 있다.
이는 고정된 시드 값(1234)을 사용했기 때문이다.
따라서, 고정된 시드 값은 항상 동일한 난수 시퀀스를 생성하며,
고정된 시드는 시드를 설정하지 않은 경우와 유사한 결과값을 보여준다는걸 확인했다.

case3🔍. 고정되지않은 시드 값을 설정한 경우, srand(time(NULL))

코드

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(0)); // 시드를 현재 시간으로 설정
    for (int i = 0; i < 5; i++) {
        int randomNumber = rand(); // 난수 생성
        printf("Random number %d: %d\n", i + 1, randomNumber);
    }
    return 0;
}

실행 결과

시드 값이 매번 달라지기 때문에, 프로그램을 실행할 때마다 다른 난수가 출력된다.
-> 동일한 난수 시퀀스X

Random number 1: 1357924680
Random number 2: 975312468
Random number 3: 24561379
Random number 4: 19823475
Random number 5: 762453987

다시 실행하면

Random number 1: 1736482934
Random number 2: 126487239
Random number 3: 18273645
Random number 4: 91827365
Random number 5: 46283756

요약

  • 시드 값을 설정하지 않으면, rand()는 항상 동일한 난수 시퀀스를 생성한다.
  • 고정된 시드 값을 설정하면, 매번 실행할 때마다 동일한 난수 시퀀스를 생성한다.
  • 시드를 현재 시간으로 설정하면, 매번 실행할 때마다 다른 난수 시퀀스를 생성한다.

난수 생성 도구들 : rand(), srand(), time(), NULL

📒rand() 함수

  • #include <stdlib.h> 에 정의되어있다.

  • rand() 함수는 난수(임의의 숫자)를 생성하는 함수이다.

  • 호출할 때마다 0에서 RAND_MAX 사이의 숫자를 반환한다. (RAND_MAX는 대게 32676)

📒srand() 함수

  • #include <stdlib.h> 에 정의되어있다.

  • rand() 함수가 생성하는 난수의 시드를 설정하기 위해 사용됩니다.

  • 시드 값은 난수 생성기의 초기 상태를 결정하고, 시드 값에 따라 난수 시퀀스가 결정된다.

  • 고정된 시드값이냐 아니냐가 중요하다.

    예시 상황 :

    • 게임 맵 생성: 림월드나 마크처럼 랜덤 맵을 생성하는 게임에서는 시드 값을 변경하여 다양한 맵을 생성한다.
    • 데이터 샘플링: 시드 값을 고정하면 동일한 샘플링 결과를 재현할 수 있어 유용하다.

📒time() 함수

  • #include <time.h> 에 정의되어있다.

  • time() 함수는 현재 시간을 가져오는 함수이다.

  • 주로 srand()의 시드를 설정할 때 많이 사용된다.

  • 1970년 1월 1일 00:00:00 UTC 이후 경과된 초를 나타낸다.

📒NULL 포인터 타입의 상수

  • 포인터가 아무것도 가리키지 않는다는 것을 의미한다.

  • 내부적으로, time 함수는 인자로 전달된 포인터가 NULL인지 확인한다. 만약 NULL이면, 단순히 현재 시간을 반환하고, 그렇지 않으면 전달된 포인터가 가리키는 위치에 현재 시간을 저장하고 반환한다.

  • C 표준에서는 NULL이 보통 ((void*)0)으로 정의되어 있기 때문에 포인터 문맥에서 0은 NULL과 동일하게 사용될 수 있다.

  • 따라서 time(NULL)과 time(0)은 모두 현재 시간을 반환하는 데 사용한다.


📌결론 : real랜덤한 난수 생성 코드

srand(time(NULL)); // 시드를 현재 시간으로 설정하여 매번 다른 난수 시퀀스 생성
...
rand()사용
profile
molbwa

0개의 댓글