C/C++
C 언어에서 난수를 만들려면 rand() 함수를 이용합니다. rand()는 0 부터 RAND_MAX 사이의 난수를 생성합니다. 32bit 리눅스 시스템에서 RAND_MAX값은 2147483647입니다. 즉, int 변수값의 양의 값 최대값입니다.
난수 생성에는 rand()
일단 예제를 보시겠습니다.
#include <stdio.h> #include <stdlib.h> int main( void) { int ndx; printf( "RAND_MAX = %dn", RAND_MAX); for ( ndx = 0; ndx < 5; ndx++) { printf( "%d %dn", ndx, rand()); } return 0; }
실행하면 아래와 같습니다.
]$ ./ss RAND_MAX = 2147483647 0 1804289383 1 846930886 2 1681692777 3 1714636915 4 1957747793 ]$
0에서 int 변수 값중 가장 큰 양의 값을 가지므로 원하는 범위의 값을 구하기 위해서는 나머지 이용합니다. 즉, 1부터 100 사이의 난수를 구하려면,
printf( "%d %dn", ndx, rand() % 100 +1);
그러나 문제가 있습니다. rand()는 난수를 만들지만 실행할 때 마다 같은 난수를 같은 순서로 만들어 낸다는 점입니다.
#include <stdio.h> #include <stdlib.h> int main( void) { int ndx; for ( ndx = 0; ndx < 5; ndx++) printf( "%d %dn", ndx, rand() % 100 +1); return 0; }
이 프로그램을 연속으로 실행 시켜 보겠습니다.
]$ ./a.out 0 84 1 87 2 78 3 16 4 94 ]$ ./a.out 0 84 1 87 2 78 3 16 4 94 ]$
실행할 때마다 같은 난수가 같은 순서로 생성됩니다. 그러므로 실행할 때 마다 새로운 난수를 생성할 수 있도록 난수를 생성하는 기초값, 즉 seed 값을 바꾸어 주어야 합니다. 난수의 seed는 srand()를 사용하여 변경할 수 있습니다.
난수 생성을 위한 seed 지정 srand()
그러나 같은 seed 값을 사용한다면 어떻게 될까요?
#include <stdio.h> #include <stdlib.h> int main( void) { int ndx; srand( 99); for ( ndx = 0; ndx < 5; ndx++) printf( "%d %dn", ndx, rand() % 100 +1); return 0; }
]$ ./a.out 0 73 1 25 2 50 3 14 4 70 ]$ ./a.out 0 73 1 25 2 50 3 14 4 70 ]$
아까와는 다른 난수이지만 역시 실행할 때 마다 같은 난수가 같은 순서로 생성됩니다. 그러므로 실행할 때 마다 난수의 seed 값을 매번 다른 값으로 지정해 주어야 합니다.
이 seed 값으로 사용하는 것이 시간입니다. time.h 에 선언된 timc() 함수는 초단위의 현재 시간값을 받습니다. 해서 아래 처럼 프로그램을 바꾸었습니다.
#include <stdio.h> #include <stdlib.h> #include <time.h> int main( void) { int ndx; srand( time( NULL)); for ( ndx = 0; ndx < 5; ndx++) printf( "%d %dn", ndx, rand() %100 +1); return 0; }
실행하면 실행할 때 마다 새로운 난수가 생성되는 것을 보실 수 있습니다.
]$ ./a.out 0 23 1 3 2 40 3 17 4 81 ]$ ./a.out 0 71 1 31 2 1 3 88 4 91 ]$참고로 약간 병적인(?) 얘기를 하겠습니다. 이 프로그램을 빠르게 실행하면 아래와 같이 같은 난수가 출력될 수 있습니다.
]$ ./a.out 0 65 1 79 2 4 3 7 4 15 ]$ ./a.out 0 65 1 79 2 4 3 7 4 15 ]$왜 일까요? srand() 에 time()까지 사용했는데 이렇게 난수가 중복되는 경우가 생겼을 까요? 그것은 time()이 초 단위이기 때문입니다. srand()는 프로그램 시작 시에 한 번 사용하면 되기 때문에 1초 이내에, 더 정확히 말씀 드려서 같은 초 시간에 연속으로 실행되면 이와 같이 난수가 중복될 수 있습니다.
그러나 이런 경우는 극히 드물겠죠. 드물더라도 이런 경우가 없다고 보장할 수 없다고 생각하고 깨름직하다면 getpid()를 사용하시면 됩니다. getpid()는 현재 실행 중인 프로세스의 아이디를 구해줍니다. 같은 프로그램을 실행해도 실행할 때 마다 프로세스 아이디는 증가되기 때문에 매번 다른 값을 반환하게 됩니다.
그러나 이 프로세스 아이디를 사용하기에는 무리가 있습니다. 왜냐하면 시스템이 리부팅이 되면 프로세스 아이디는 초기화가 되기 때문이죠. 이런 이유로 time()함수값과 같이 사용합니다.
#include <stdio.h> #include <stdlib.h> #include <time.h> // time() #include <unistd.h> // getpid() int main( void) { int ndx; srand( (unsigned)time(NULL)+(unsigned)getpid()); for ( ndx = 0; ndx < 5; ndx++) printf( "%d %dn", ndx, rand() %100 +1); return 0; }태그 : *gcc *C언어
이부분에서요 100은 까지 수중에 난수를 만드는데 +1은 왜잇는건가요?? 없어도 차이가 없어보이던데...