카테고리 없음

C++ time 함수와 rand, srand 함수

sudo 2021. 7. 14. 03:57

C++에서는 <ctime>헤더에 포함된 time 함수를 제공한다. time 함수의 원형은 다음과 같다

time_t time(time_t *pTime)

여기서 time_t는 시간을 나타내기 위해 만들어진 데이터 타입인데 __int64와 같다.

typedef __time64_t time_t;
typedef __int64                       __time64_t;

time 함수는 1970년 1월 1일을 기준으로 1초씩 증가해서 함수 호출 당시에는 몇초가 지났는지를 반환해준다.

사용법은 아래와 같이 두가지가 있다.

time_t t1 = time(nullptr); //방법 1, nullptr 대신 0을 줘도 무관

time_t t2;
time(&t2); // 방법 2

time 함수의 기능이 1970년 1월 1일을 기준으로 1초씩 증가한다고 했다. 이 말은 매번 time 함수가 포함된 프로그램을 실행할 때 마다 값이 다르다는 의미다(물론 1초에 여러번 실행하는 걸 제외하고). 이 특징을 이용할 수 있는 곳이 있는데 바로 난수를 만들때이다.

 

가장 기본적인 난수발생 함수는 rand()이다. 하지만 rand 함수는 완벽한 난수를 만들어내지 못한다 예를 들어서

int main()
{
    std::cout << rand() << std::endl;
    std::cout << rand() << std::endl;
    std::cout << rand() << std::endl;

    return 0;
}

이 코드를 여러번 실행하면 매번 같은 값이 나오는 것을 확인할 수 있다. 이 말은 곧 rand 함수는 완전한 난수를 만들어내지 못하고 있다는 의미다. 사실 rand함수란 랜덤한 값을 포함하고 있는 표에서 난수를 가져오는 것인데 이 표를 바꾸지 않고 매번 같은 표에서 난수를 가져오기 때문에 위와 같은 현상이 일어나는 것이다.

 

이 때 완벽한 난수를 만들기 위해서 프로그램이 실행될 때 마다 다른 seed값을 줘야 하는데, 아까 배운 time 함수를 이용하면 매 초마다 다른 seed값을 만들어낼 수 있을 것이다. seed값을 주는 함수는 srand를 이용하면 된다. 함수 원형은 아래와 같다.

void srand (unsigned int seed)

srand함수와 time함수를 이용하면 완전한 난수를 만들어낼 수 있다.

int main()
{
	srand(time(0));
	rand(); // 가급적 사용하지 않기

	// 난수 생성
	std::cout << "random number: "<< rand() << std::endl;

    return 0;
}

srand함수와 time함수를 사용해서 seed값을 전달한 바로 뒤 첫번째 rand는 완전한 난수가 아닌 듯 보인다. 사용해보면 일정한 값에서 조금씩 증가하기만 할 뿐 완전한 난수가 아니다. 그 이유는 stackoverflow에서 찾을 수 있었다.

해석해보면 seed값끼리 너무 가까워서 난수 발생기가 발산하기 까지 충분한 시간이 없기 때문에 라고 한다. 아마 seed값을 줄 때 마다 몇초씩 밖에 차이가 안나서 그런 것 같다. 각 실행의 seed값도 서로 차이가 크게 한다면 해결 이 문제도 해결할 수 있었다.

 

Reference

https://blockdmask.tistory.com/308

 

[C언어/C++] rand, srand, time 랜덤함수에 대해서 (난수생성)

안녕하세요. BlockDMask 입니다. 오늘은 C/C++로 개발할때 가끔 사용하는 랜덤한 수(난수)를 생성하는 함수에 대해서 알아보겠습니다. 랜덤한 값을 가지고올때 필요한데요. 그럼 시작해보겠습니다. 1

blockdmask.tistory.com

https://stackoverflow.com/questions/27301090/first-rand-generates-the-same-value-after-srandtime0

 

first rand() generates the same value after srand(time(0))

srand(time(0)) does not seem to be seeding rand() correctly, the 1st number generated is always the same. This is running on OS X, is there something wrong with my settings or my code? I do wait a

stackoverflow.com