Подтвердить что ты не робот

Генерировать случайные двойные числа в С++

Как генерировать случайные числа между двумя удвоениями в С++, эти числа должны выглядеть как xxxxx, yyyyy.

4b9b3361

Ответ 1

Вот как

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

Не забудьте вызвать srand() с правильным посевом каждый раз, когда запускается ваша программа.

Ответ 2

Для этого решения требуется С++ 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 "Генерация случайных чисел с использованием С++ TR1" .

См. также Stroustrup "Генерация случайных чисел" .

Ответ 3

Если точность здесь является проблемой, вы можете создавать случайные числа с более мелкой градацией путем рандомизации значимых бит. Предположим, что мы хотим иметь двойное значение между 0.0 и 1000.0.

В 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 бит) больше числа бит двойной мантиссы (53 бит для IEE 754) на всех платформах или нет. Вероятно, "умный" должен включать проверку типа if (sizeof(unsigned long long)*8 > num_mant_bits) ..., если это не так.

Ответ 4

Этот фрагмент прямо из Stroustrup Язык программирования С++ (4-е издание), §40.7; для этого требуется С++ 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;
}

Ответ 5

Это должно быть реалистичным, потокобезопасным и достаточно гибким для многих применений:

#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';
}

Ответ 6

что-то вроде этого:

#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;
}

Ответ 7

  • Это для С++
#include "stdafx.h"
#include "iostream"
#include "ctime"

using namespace std;

double getRandom(double min, double max)
{
    double before = rand() % (int)max + (int)min;
    double after = (double)rand() / RAND_MAX;
    double result = before + after;
    if (result < min || result > max) {
        result = getRandom(min, max);
    }
    return result;
}

int main()
{
    srand (time(NULL));
    for (int i = 0; i < 100; i++) {
        double number = getRandom(-1.57079632679, 1.57079632679);
        cout << number << endl;
    }
    system("pause");
}