Nice programing

0과 1 사이의 rand ()

nicepro 2020. 11. 14. 11:07
반응형

0과 1 사이의 rand ()


따라서 다음 코드는 0 <r <1을 만듭니다.

r = ((double) rand() / (RAND_MAX))

r = ((double) rand() / (RAND_MAX + 1))-1 <r <0 만드는 이유는 무엇 입니까?

RAND_MAX에 하나를 추가하면 1 <r <2가되지 않습니까?

편집 : 나는 경고를 받고 있었다 : 식의 정수 오버플로

그게 문제가 될 수 있습니다. 방금했고 cout << r << endl확실히 -1과 0 사이의 값을 제공합니다.


이것은 전적으로 구현 고유의 것 ,하지만 당신이 작업하고있는 C ++ 환경에서 나타납니다 RAND_MAX같다 INT_MAX.

이로 인해 RAND_MAX + 1정의되지 않은 (오버플로) 동작을 나타내며 INT_MIN. 초기 명령문이 (0과 INT_MAX) / ( 사이의 무작위 # )를 나누고 INT_MAX값을 생성하는 0 <= r < 1동안 이제 (0과 INT_MAX) / ( 사이의 임의 #)를 나누고 INT_MIN값을 생성합니다.-1 < r <= 0

난수를 생성 1 <= r < 2하려면 다음을 원할 것입니다.

r = ((double) rand() / (RAND_MAX)) + 1

rand() / double(RAND_MAX)0 (포함)과 1 ( 포함 ) 사이의 부동 소수점 난수를 생성 하지만 다음과 같은 이유로 좋은 방법이 아닙니다 (RAND_MAX는 일반적으로 32767이기 때문).

  1. 생성 할 수있는 다른 난수의 수가 너무 적습니다 : 32768. 더 많은 다른 난수가 필요하면 다른 방법이 필요합니다 (코드 예제는 아래에 나와 있습니다).
  2. 생성 된 숫자는 너무 조잡합니다. 1/32768, 2/32768, 3/32768을 얻을 수 있지만 그 사이에는 아무것도 없습니다.
  3. 난수 생성기 엔진의 제한된 상태 : RAND_MAX 난수를 생성 한 후 구현은 일반적으로 동일한 난수 시퀀스를 반복하기 시작합니다.

위의 rand () 제한으로 인해 0 (포함)과 1 ( 배타적 ) 사이의 난수 생성을위한 더 나은 선택 은 다음 코드 조각입니다 ( http://en.cppreference.com/w 의 예제와 유사) . / cpp / numeric / random / uniform_real_distribution ) :

#include <iostream>
#include <random>
#include <chrono>

int main()
{
    std::mt19937_64 rng;
    // initialize the random number generator with time-dependent seed
    uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
    std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
    rng.seed(ss);
    // initialize a uniform distribution between 0 and 1
    std::uniform_real_distribution<double> unif(0, 1);
    // ready to generate random numbers
    const int nSimulations = 10;
    for (int i = 0; i < nSimulations; i++)
    {
        double currentRandomNumber = unif(rng);
        std::cout << currentRandomNumber << std::endl;
    }
    return 0;
}

으로 대체 unif(0, 1)하여 1 (포함)과 2 (제외) 사이의 난수를 생성하도록 쉽게 수정할 수 unif(1, 2)있습니다.


No, because RAND_MAX is typically expanded to MAX_INT. So adding one (apparently) puts it at MIN_INT (although it should be undefined behavior as I'm told), hence the reversal of sign.

To get what you want you will need to move the +1 outside the computation:

r = ((double) rand() / (RAND_MAX)) + 1;

It doesn't. It makes 0 <= r < 1, but your original is 0 <= r <= 1.

Note that this can lead to undefined behavior if RAND_MAX + 1 overflows.


My guess is that RAND_MAX is equal to INT_MAX and so you're overflowing it to a negative.

Just do this:

r = ((double) rand() / (RAND_MAX)) + 1;

Or even better, use C++11's random number generators.


This is the right way:

double randd() {
  return (double)rand() / ((double)RAND_MAX + 1);
}

or

double randd() {
  return (double)rand() / (RAND_MAX + 1.0);
}

In my case (I'm using VS 2017) works fine the following simple code:

#include "pch.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(time(NULL));

    for (int i = 1000; i > 0; i--) //try it thousand times
    {
        int randnum = (double)rand() / ((double)RAND_MAX + 1);
        std::cout << " rnum: " << rand()%2 ;
    }
} 

참고URL : https://stackoverflow.com/questions/9878965/rand-between-0-and-1

반응형