generowanie losowych liczb podwójnych w c++

Jak wygenerować liczby losowe pomiędzy dwoma sobowtórami w c++, liczby te powinny wyglądać jak xxxxx,yyyyy .

 83
Author: Radi, 2010-04-24

6 answers

Oto jak

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

Pamiętaj, aby wywoływać srand () z odpowiednim nasieniem za każdym razem, gdy program się uruchomi.

[edytuj] Ta odpowiedź jest przestarzała, ponieważ C++ ma natywną bibliotekę losową opartą na nie-C (zobacz odpowiedź Alessandro Jacopsons) Ale to nadal dotyczy C

 116
Author: rep_movsd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 18:03:01

To rozwiązanie wymaga C++11 (lub 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;
}

Aby uzyskać więcej szczegółów zobacz John D. Cook ' s "Random number generation using C++ TR1".

Zobacz także Stroustrupa "Generowanie liczb losowych".

 104
Author: Alessandro Jacopson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-16 09:47:55

To powinno być wydajne, bezpieczne dla nici i wystarczająco elastyczne dla wielu zastosowań:

#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';
}
 10
Author: Galik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-28 20:04:22

Jeśli dokładność jest tutaj problemem, możesz tworzyć liczby losowe z drobniejszą podziałką poprzez losowanie znaczących bitów. Załóżmy, że chcemy mieć podwójne między 0.0 i 1000.0.

Na MSVC (12 / Win32) RAND_MAX to na przykład 32767.

Jeśli użyjesz wspólnego schematu rand()/RAND_MAX twoje luki będą tak duże jak

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

W przypadku IEE 754 zmiennych podwójnych (53 znaczące bity) i 53 bitowej randomizacji najmniejszą możliwą lukę randomizacyjną dla problemu od 0 do 1000 będzie

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

I dlatego znacznie niższe.

Minusem jest to, że 4 wywołania rand() będą potrzebne do uzyskania randomizowanej liczby całkowitej (przy założeniu 15-bitowego 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);
}

Jeśli liczba bitów dla mantysy lub RNG jest nieznana, należy uzyskać odpowiednie wartości w funkcji.

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

Uwaga: Nie wiem czy liczba bitów dla unsigned long long (64 bit) jest większa niż liczba bitów podwójnych mantissa (53 bit dla IEE 754) na wszystkich platformach lub nie. Prawdopodobnie byłoby "mądrze" dołączyć czek taki jak if (sizeof(unsigned long long)*8 > num_mant_bits) ..., jeśli tak nie jest.

 7
Author: Pixelchemist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-08 00:37:26

Ten fragment jest prosto z Stroustrupa język programowania C++ (wydanie 4), §40.7; wymaga 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;
}
 3
Author: Alessandro Jacopson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-16 09:30:47

Coś takiego:

#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;
}
 0
Author: Oleg Razgulyaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-24 13:13:41