Programing

C ++에서 임의의 이중 숫자 생성

lottogame 2020. 10. 23. 07:32
반응형

C ++에서 임의의 이중 숫자 생성


C ++에서 두 double 사이에 난수를 생성하는 방법은이 숫자가 xxxxx, yyyyy와 같아야합니다.


방법은 다음과 같습니다.

double fRand(double fMin, double fMax)
{
    double f = (double)rand() / RAND_MAX;
    return fMin + f * (fMax - fMin);
}

프로그램이 시작될 때마다 적절한 시드로 srand ()를 호출하는 것을 잊지 마십시오.

[편집]이 답변은 C ++가 네이티브 비 C 기반 랜덤 라이브러리를 가지고 있기 때문에 쓸모가 없습니다 (Alessandro Jacopsons 답변 참조) 그러나 이것은 여전히 ​​C에 적용됩니다


이 솔루션에는 C ++ 11 (또는 TR1)이 필요합니다.

#include <random>

int main()
{
   double lower_bound = 0;
   double upper_bound = 10000;
   std::uniform_real_distribution<double> unif(lower_bound,upper_bound);
   std::default_random_engine re;
   double a_random_double = unif(re);

   return 0;
}

자세한 내용은 John D. Cook의 "C ++ TR1을 사용한 난수 생성"을 참조하십시오 .

Stroustrup의 "Random number generation"을 참조하십시오 .


여기서 정확도가 문제가되는 경우 중요한 비트를 랜덤 화하여 더 미세한 눈금으로 난수를 만들 수 있습니다. 0.0에서 1000.0 사이의 double을 원한다고 가정 해 봅시다.

MSVC (12 / Win32)에서 RAND_MAX는 예를 들어 32767입니다.

일반적인 rand()/RAND_MAX계획 을 사용하면 격차가

1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...

IEE 754 이중 변수 (53 개의 중요한 비트) 및 53 비트 무작위 화의 경우 0 ~ 1000 문제에 대해 가능한 가장 작은 무작위 화 간격은 다음과 같습니다.

2^-53 * (1000.0 - 0.0) = 1.110e-13

따라서 상당히 낮습니다.

단점은 무작위 정수를 얻기 위해 4 개의 rand () 호출이 필요하다는 것입니다 (15 비트 RNG 가정).

double random_range (double const range_min, double const range_max)
{
  static unsigned long long const mant_mask53(9007199254740991);
  static double const i_to_d53(1.0/9007199254740992.0);
  unsigned long long const r( (unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53 );
  return range_min + i_to_d53*double(r)*(range_max-range_min);
}

가수 또는 RNG의 비트 수를 알 수없는 경우 함수 내에서 각 값을 가져와야합니다.

#include <limits>
using namespace std;
double random_range_p (double const range_min, double const range_max)
{
  static unsigned long long const num_mant_bits(numeric_limits<double>::digits), ll_one(1), 
    mant_limit(ll_one << num_mant_bits);
  static double const i_to_d(1.0/double(mant_limit));
  static size_t num_rand_calls, rng_bits;
  if (num_rand_calls == 0 || rng_bits == 0)
  {
    size_t const rand_max(RAND_MAX), one(1);
    while (rand_max > (one << rng_bits))
    {
      ++rng_bits;
    }
    num_rand_calls = size_t(ceil(double(num_mant_bits)/double(rng_bits)));
  }
  unsigned long long r(0);
  for (size_t i=0; i<num_rand_calls; ++i)
  {
    r |= (unsigned long long(rand()) << (i*rng_bits));
  }
  r = r & (mant_limit-ll_one);
  return range_min + i_to_d*double(r)*(range_max-range_min);
}

참고 : 모든 플랫폼에서 unsigned long long (64 비트)의 비트 수가 이중 가수 비트 (IEEE 754의 경우 53 비트)보다 큰지 여부는 알 수 없습니다. if (sizeof(unsigned long long)*8 > num_mant_bits) ...그렇지 않은 경우 와 같은 수표를 포함하는 것이 "스마트"할 것입니다 .


This should be performant, thread-safe and flexible enough for many uses:

#include <random>
#include <iostream>

template<typename Numeric, typename Generator = std::mt19937>
Numeric random(Numeric from, Numeric to)
{
    thread_local static Generator gen(std::random_device{}());

    using dist_type = typename std::conditional
    <
        std::is_integral<Numeric>::value
        , std::uniform_int_distribution<Numeric>
        , std::uniform_real_distribution<Numeric>
    >::type;

    thread_local static dist_type dist;

    return dist(gen, typename dist_type::param_type{from, to});
}

int main(int, char*[])
{
    for(auto i = 0U; i < 20; ++i)
        std::cout << random<double>(0.0, 0.3) << '\n';
}

This snippet is straight from Stroustrup's The C++ Programming Language (4th Edition), §40.7; it requires C++11:

#include <functional>
#include <random>

class Rand_double
{
public:
    Rand_double(double low, double high)
    :r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){}

    double operator()(){ return r(); }

private:
    std::function<double()> r;
};

#include <iostream>    
int main() {
    // create the random number generator:
    Rand_double rd{0,0.5};

    // print 10 random number between 0 and 0.5
    for (int i=0;i<10;++i){
        std::cout << rd() << ' ';
    }
    return 0;
}

something like this:

#include <iostream>
#include <time.h>

using namespace std;

int main()
{
    const long max_rand = 1000000L;
    double x1 = 12.33, x2 = 34.123, x;

    srandom(time(NULL));

    x = x1 + ( x2 - x1) * (random() % max_rand) / max_rand;

    cout << x1 << " <= " << x << " <= " << x2 << endl;

    return 0;
}

참고URL : https://stackoverflow.com/questions/2704521/generate-random-double-numbers-in-c

반응형