Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 랜덤 부동 소수점(float) 값을 생성하는 방법

C나 C++에서는 float 타입의 난수를 직접 생성할 수 없습니다. 대신 약간의 트릭을 사용해야 하는데, 가장 일반적인 방법은 두 개의 난수 정수값을 만든 후 이를 나누어 부동 소수점 값을 얻는 것입니다.

이때 나눗셈 결과가 정수(몫)가 되는 경우가 간혹 발생할 수 있습니다. 이러한 가능성을 줄이기 위해 결과에 0.5 같은 부동 소수점 상수를 곱해 주기도 합니다.

기본 구현 예제

아래 예제는 rand() 함수가 반환하는 최대값인 RAND_MAX로 나누어 0.0 ~ 1.0 사이의 실수를 만들고, 여기에 원하는 범위의 최대값(5.0)을 곱하는 방식입니다.

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
    srand((unsigned int)time(NULL));
    float a = 5.0;
    for (int i = 0; i < 20; i++)
        cout << (float(rand()) / float(RAND_MAX)) * a << endl;
}

실행 결과

2.07648
4.3115
1.31092
2.22465
2.17292
1.48381
1.91137
0.56505
2.24326
4.44517
3.1695
2.39067
1.89062
4.35881
4.17524
0.189673
1.87521
1.76916
2.3217
2.20481

C++11 이상에서 권장되는 방식

rand() 함수는 난수의 품질과 범위 면에서 한계가 있으므로, C++11부터 도입된 <random> 헤더를 사용하는 것이 더 좋습니다. 아래처럼 작성하면 더 균일하게 분포된 실수 난수를 얻을 수 있습니다.

#include <iostream>
#include <random>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<float> dist(0.0f, 5.0f);

    for (int i = 0; i < 20; i++)
        std::cout << dist(gen) << '\n';
}

정리하면, 전통적인 방식은 rand()RAND_MAX로 나누어 정규화한 뒤 원하는 범위를 곱하는 것이며, 현대 C++에서는 std::uniform_real_distribution을 활용하는 것이 안전하고 권장되는 방법입니다.