개인사

[C++] std::rand, std::srand, random 헤더 본문

알고리즘 공부/C++

[C++] std::rand, std::srand, random 헤더

마달랭 2025. 12. 4. 02:33
728x90

개요

C++에서 랜덤 쪽은 두 계열로 나뉜다.

 

  • 옛날 C 스타일: rand(), srand()
  • 현대 C++ 스타일: <random> 헤더

 

 

std::rand(), std::srand()

#include<iostream>
#include<cstdlib>
#include<ctime>

int main() {
    std::srand(static_cast<unsigned>(std::time(nullptr))); // 시드
    
    int role = 10;
    while (role--) {
        int x = std::rand();           // 0 ~ RAND_MAX
        int dice = x % 6 + 1;          // 1 ~ 6
        std::cout << dice << " ";
    }
}

총 10회의 주사위를 돌렸고, 난수가 추출되었다.

 

플랫폼에 의존 해야 하므로 품질이 안좋을 수 있다.

범위 조절을 직접 % 같은 걸로 해야 해서 실수하기 쉽다.

쓰레드 환경/재현성 제어 같은 면에서 불편하다.

 

이러한 이유로 인해 C스타일은 옛날 방식으로 요즘 C++에선 학습용이 아니면 잘 안쓴다고 한다.

 

 

random 헤더(C++11)

랜덤을 구현하는 패턴은 항상 3단계이다.

  1. 난수 엔진 선택: 어떤 PRNG를 쓸지
  2. 시드(seed) 넣기
  3. 분포(distribution) 정하기
#include<algorithm>
#include<random>
#include<iostream>

int main() {
    // 1. 엔진 + 시드
    std::random_device rd;        // OS에서 랜덤 시드 얻기
    std::mt19937 gen(rd());       // Mersenne Twister 엔진

    // 2. 분포 정의: 1 ~ 6
    std::uniform_int_distribution<int> d(1, 6);

    // 3. 사용: 호출할 때마다 난수 하나
    for (int i = 0; i < 10; ++i) {
        int dice = d(gen);
        std::cout << dice << ' ';
    }
    std::cout << '\n';
    
    // 실수 뽑기
    std::uniform_real_distribution<double> f(0.0, 1.0);
    for (int i = 0; i < 10; ++i) {
        double rate = f(gen);
        std::cout << rate << ' ';
    }
    std::cout << '\n';

    // 벡터 내부를 shuffle하기
    std::vector<int> v{ 1,2,3,4,5 };
    std::shuffle(v.begin(), v.end(), gen);
    for (int i : v) std::cout << i << ' ';
    std::cout << '\n';
}

 

 

시드와 재현성

std::mt19937 gen(1234);  // 항상 같은 시퀀스 생성

재현 가능한 랜덤(테스트용) 원하면 시드를 고정하면 된다.

 

std::random_device rd;
std::mt19937 gen(rd());

매번 다른 랜덤이 필요하면 std::random_device로 시드 초기화

 

 

멀티스레드에서 활용

스레드마다 자기 전용 엔진을 갖는 게 좋다.

thread_local std::mt19937 gen(std::random_device{}());

이렇게 하면 각 스레드가 자기 gen을 가지고, 락 없이 안전하게 랜덤을 쓸 수 있다.

 

 

결론

 

std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<int> dist(a, b);
int x = dist(gen);
  • 되도록 rand() 말고 <random> 사용하기
  • 실수는 uniform_real_distribution, 섞기는 std::shuffle, 그 외 필요한 분포는 <random>에 웬만한 건 다 있음.

 

728x90