그거 아시나요? 사실 우리가 아는 Random은 사실 "랜덤"하지 않습니다.
컴퓨터는 기본적으로 무작위 수를 절대 뽑아낼 수 없는데요.
그럼 랜덤한 값을 뽑는 기능들은 어떤식으로 만드는 것일까요?
난수
정의된 범위 내에서 무작위로 뽑힌 수.
C++에서 난수를 가장 쉽게 구할 수 있는 함수가 있습니다. 바로 rand()라는 함수인데요.
#include<iostream>
using namespace std;
int main()
{
int num;
num = rand();
cout << num << endl;
}
rand로 뽑은 값을 출력해보면 아마 이런 값이 나올 겁니다.

분명 난수라 하였는데 rand를 호출해보니 계속 41만 출력하는데 무슨 일일까요?
이번에는 한번 10번 반복해서 출력해봅시다.
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; ++i)
{
cout << rand() << endl;
}
}

이렇게 10번 출력하니 각각 다른 값이 나옵니다! 역시 난수였군요!
하지만 다시 실행해보니 이 또한 1번째 값부터 10번째값이 다 똑같이 나옵니다.
일단 왜 그런지 보기전에 srand()라는 함수를 먼저 봐봅시다.
#include<iostream>
using namespace std;
int main()
{
srand(2);
for (int i = 0; i < 10; ++i)
{
cout << rand() << endl;
}
}

아까와는 다르게 다른 값들이 나옵니다.
srand는 무엇이고 rand는 정확히 무엇을 하는 함수이길래 이런 일이 일어날까요?
컴퓨터에서의 난수는 이미 정해져있다

위 표는 난수 테이블의 일부를 그려본 것입니다.
보면 srand에 매개변수로 입력한 수에 맞게 rand로 값을 뽑았을 때 위에 수열대로 나오는 걸 알 수 있습니다.
srand는 rand가 출력할 시드를 정해주는 함수며 rand는 정해진 시드에 난수들을 출력하는 것입니다.
rand가 난수를 뽑는 원리는 알겠는데 이걸 가지고 어떻게 random을 만드나요?
예를 들어서 0 ~ 9중에서 숫자 하나를 뽑고 싶을 땐 어쩌죠?
rand를 활용해서 충분히 C#의 Random과 다른 언어의 랜덤 함수처럼 범위를 정하고 랜덤값을 뽑을 수 있습니다.
#include<iostream>
using namespace std;
int main()
{
for (int i = 0; i < 10; ++i)
{
cout << rand() % 10 << endl;
}
}
rand값으로 뽑은 값들을 %(나머지 연산자)로 나눠보면 10의 배수로는 모두 나누어떨어지기 때문에 0~9까지에 수를 뽑아내는 로직을 만들 수 있습니다.
그럼 1 ~ 6처럼 0으로 시작하지않는 범위는 어떤식으로 구현할까요?
cout << rand() % 6 + 1 << endl;
나머지들에 6으로 나눈 다음 나머지에 +1을 해주면 됩니다.

어? 근데 실행할 때마다 똑같은 수만 나와요!
srand함수가 계속 3번째 시드에서만 고르도록 설정하고 있기 때문입니다.
그래서 컴퓨터에서 유일하게 실시간으로 계속 바뀌는 데이터인 "시간"을 활용해서 가장 간단한 랜덤 알고리즘을 써보겠습니다.
#include<iostream>
using namespace std;
int main()
{
srand((unsigned int)time(NULL));
for (int i = 0; i < 10; ++i)
{
cout << rand() % 10 + 1 << endl;
}
}
time(NULL) 또는 time(0)은 1970년 기준으로 현재까지 흐른 시간을 int_64형식으로 초로 반환합니다.
하지만 time안에 들어가는 값 자체가 포인터여야하기 때문에 nullptr로 넣어주면 더 좋습니다.
srand를 현재 시간으로 갱신함으로써 실행할 때마다 다른 값이 나오게됩니다.
이 알고리즘이 C++에서 구현할 수 있는 제일 쉬운 알고리즘이며 다음에는 "메르센 트위스터"라는 진짜 랜덤 알고리즘을 알아보겠습니다.