난수 생성

1 minute read


rand()

난수는 무작위로 정해진 수를 말한다. c에서는 stdlib.h 라이브러리에서 지원하는 rand()함수를 통해서 난수를 만들 수 있다.

#include <stdlib.h>

int main()
{	
	for (int i = 0; i < 10; i++)
	{
		int randNum = rand();
		printf("%d\n", randNum);
	}

	return 0;
}

// 출력 결과
// 41
// 18467
// 6334
// 26500
// 19169
// 15724
// ...

무작위 처럼 보이는 숫자들이 생성되었다. 이 숫자들과 나눗셈의 특징을 활용하면 원하는 범위 내의 난수가 생성이 가능하다.
어떠한 숫자를 나누든 나누는 나머지는 0 ~ 나눈숫자 - 1의 크기를 가지게 된다.

int main()
{
	for (int i = 0; i < 10; i++)
	{
		int randNum = rand();
		// 5로 나누었기 때문에 0 ~ 4 범위의 난수가 생성된다.
		printf("%d, %d\n", randNum, randNum % 5);
	}

	return 0;
}

// 출력 결과
// 41, 1
// 18467, 2
// 6334, 4
// 26500, 0
// 19169, 4
// 15724, 4
// ...

rand() % b;  //0 ~ ( b - 1 ) 사이의 수를 생성한다. 
rand() % b + 1; // 1 ~ b 사이의 수를 생성한다.
rand() % b + a; // a ~ ( b - 1 + a ) 사이의 수를 생성한다.
rand() % ( b + 1 - a ) + a; // a ~ b 사이의 수를 생성한다. 

하지만 컴파일을 아무리 반복해도 순서와 숫자들이 바뀌지 않고 일정하게 출력된다.

그 이유는 라이브러리 상에 존재하는 이미 저장된 난수들을 순서대로 가져와서 사용하기 때문에 항상 일정한 숫자들이 출력된다.


srand()

rand() 함수는 사실상 난수가 아닌 정해진 숫자들이기 때문에 무작위의 기능을 할 수 가 없게 된다.

srand 함수는 인자로 받은 값을 seed로 사용해서 rand의 정해진 숫자들을 불규칙하게 바꾸어준다. 매번 바뀌는 난수를 얻기 위해서는 이 seed 값도 계속해서 바뀌어야 하기 때문에 시간을 인자로 쓰는 방식이 많이 사용된다.

time.h 라이브러리에 포함된 함수 time()은 매초 단위의 시간을 반환한다.

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

int main()
{
	// 시간은 양수뿐이기 때문에
	srand(unsigned int(time(NULL)));
	

	for (int i = 0; i < 10; i++)
	{
		int randNum = rand() % 10;
		printf("%d\n", randNum);
	}

	return 0;
}

결국 이 방법도 일정하게 흘러가는 시간을 시드로 받아서 생성하는 것이기 때문에 완전한 난수라고 볼 수 는 없다. 현재까지는 컴퓨터로는 완전한 난수를 만들어 내는것은 불가능하고 난수에 가까운 수를 만드는 방법 밖에 없다고 한다.