rand() % N 은 왜 확률을 틀어지게 할까 | 드랍률 1억 번 시뮬레이션 (C++)
windwolf_clan
0:00 / 0:00
rand() % N 은 왜 확률을 틀어지게 할까 | 드랍률 1억 번 시뮬레이션 (C++)
403 просмотра · 4 дн. назад
windwolf_clan
38 подписчиков
403 просмотра · 4 дн. назад
게임에서 rand() % 10000 == 0 으로 만든 드랍은 정말 만분의 1일까요? 1억 번 뽑아 보니 의도한 10,000번이 아니라 12,078번이 나왔습니다(MSVC·seed 12345 기준). RAND_MAX 와 나머지 연산으로 왜 확률이 틀어지는지 풀고, 버리고 다시 뽑기와 uniform_int_distribution 으로 고칩니다.
C++20, MSVC(cl /EHsc /std:c++20), seed 12345, 최적화 없음. 숫자는 이 코드를 실제로 실행한 값입니다. 환경·시드에 따라 달라집니다.
복사하면 전각 꺾쇠 < > 를 반각 꺾쇠로 되돌려 주세요.
#include <iostream>
#include <cstdlib>
#include <random>
using namespace std;
int roll() {
int r;
do r = rand(); while (r >= 30000);
return r % 10000;
}
int main() {
const long long N = 100000000LL;
long long a = 0, b = 0, c = 0;
srand(12345);
for (long long i = 0; i < N; i++)
if (rand() % 10000 == 0) a++;
srand(12345);
for (long long i = 0; i < N; i++)
if (roll() == 0) b++;
mt19937 gen(12345);
uniform_int_distribution<int> dist(0, 9999);
for (long long i = 0; i < N; i++)
if (dist(gen) == 0) c++;
cout << a << "\n" << b << "\n" << c << "\n";
}
챕터
0:00 인트로
0:41 문제 상황
1:17 rand() 가 내는 값
1:48 나머지 연산이 하는 일
3:00 실제 확률
3:25 1억 번 시뮬레이션
3:58 고치는 법 ① 버리고 다시 뽑기
4:58 고치는 법 ② random 라이브러리
5:51 알아둘 점
6:32 정리
#cpp #게임개발 #프로그래밍