NAME
rand, rand_r, srand - 유사 난수 생성기
SYNOPSIS
#include <stdlib.h>
int rand(void);
int rand_r(unsigned int *seedp);
void srand(unsigned int seed);
glibc 기능 확인 매크로 요건 (feature_test_macros(7) 참고):
rand_r():-
- glibc 2.24부터:
_POSIX_C_SOURCE >= 199506L- glibc 2.23 및 이전:
_POSIX_C_SOURCE
DESCRIPTION
rand() 함수는 0에서 RAND_MAX까지 범위의 (경계 포함) 유사 난수 정수를 반환한다. (즉, 수학적 범위가 [0, RAND_MAX]이다.)
srand() 함수는 그 인자를 rand()가 새로 반환할 유사 난수 정수 열의 시드로 설정한다. 같은 시드 값으로 srand()를 호출하여 그 정수 열을 반복할 수 있다.
시드 값을 제공하지 않으면 rand() 함수에서 자동으로 1 값을 시드로 삼는다.
rand() 함수는 재진입 가능하지 않다. 각 호출마다 바뀌는 숨겨진 상태를 사용하기 때문이다. 그 상태라는 것은 그저 다음 호출에서 사용할 시드 값일 수도 있고 더 정교한 무언가일 수도 있을 것이다. 스레드 사용 응용에서 재연 가능한 동작 방식을 얻기 위해선 이 상태를 명시적으로 만들어야 하는데, 재진입 가능 함수인 rand_r()을 사용하면 된다.
rand()와 마찬가지로 rand_r()은 [0, RAND_MAX] 범위 내의 유사 난수 정수를 반환한다. seedp 인자는 호출들 간에 상태 저장에 쓰이는 unsigned int의 포인터이다. seedp가 가리키는 정수의 최초 값을 같게 해서 rand_r()을 호출하고 호출들 사이에서 그 값을 변경하지 않으면 동일한 유사 난수 열이 나오게 된다.
rand_r()의 seedp 인자가 가리키는 값은 아주 작은 양의 상태만 제공하므로 이 함수는 약한 유사 난수 생성기일 것이다. 대신 drand48_r(3)을 시도해 보라.
RETURN VALUE
rand() 및 rand_r() 함수는 0에서 RAND_MAX 사이의 (경계 포함) 값을 반환한다. srand() 함수는 아무 값도 반환하지 않는다.
ATTRIBUTES
이 절에서 사용하는 용어들에 대한 설명은 attributes(7)를 보라.
| 인터페이스 | 속성 | 값 |
|---|---|---|
rand(), rand_r(), srand() |
스레드 안전성 | MT-Safe |
CONFORMING TO
rand() 및 srand() 함수는 SVr4, 4.3BSD, C89, C99, POSIX.1-2001을 준수한다. rand_r() 함수는 POSIX.1-2001에서 온 것이다. POSIX.1-2008에서 rand_r()을 구식으로 표시하고 있다.
NOTES
리눅스 C 라이브러리에 있는 rand() 및 srand() 버전은 random(3) 및 srandom(3)과 같은 난수 생성기를 사용하므로 하위 비트들이 상위 비트들만큼 임의적일 것이다. 하지만 오래된 rand() 구현들에서는, 그리고 다른 시스템들의 현행 구현에서는 하위 비트들이 상위 비트들보다 훨씬 덜 임의적이다. 이식성을 의도한 응용에서 좋은 난수성이 필요할 때는 이 함수를 사용하지 말아야 한다. (대신 random(3)을 사용하라.)
EXAMPLES
POSIX.1-2001에서 rand() 및 srand()의 구현 예시로 다음을 제시하고 있다. 서로 다른 머신에서 동일한 수열이 필요할 때 유용할 수도 있을 것이다.
static unsigned long next = 1;
/* RAND_MAX가 32767이라고 가정 */
int myrand(void) {
next = next * 1103515245 + 12345;
return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned int seed) {
next = seed;
}
다음 프로그램을 이용해 특정 시드가 주어졌을 때 rand()가 만들어 내는 유사 난수 열을 표시할 수 있다.
#include <stdlib.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
int j, nloops;
unsigned int seed;
if (argc != 3) {
fprintf(stderr, "Usage: %s <seed> <nloops>\n", argv[0]);
exit(EXIT_FAILURE);
}
seed = atoi(argv[1]);
nloops = atoi(argv[2]);
srand(seed);
for (int j = 0; j < nloops; j++) {
r = rand();
printf("%d\n", r);
}
exit(EXIT_SUCCESS);
}
SEE ALSO
2021-03-22